How can I call a MySQL procedure in where clause?
In the example demo is a table name get_name() is a function and 1 is a parameter (id) .
select * from demo where name = (select name from call get_name(1))
You should use a function instead of a procedure. A procedure returns a (one or multiple) result sets (tables), whereas a function returns a single value.
You should think twice before using functions in where-clause, if they contain select clauses from the database, as it may lead into situation where the query optimizer unable to optimize the query path resulting serialized queries and poor performance. If the data amount is small or you are ok with the possible performance hit, this would work.
Related
In case I only provide a single value, are the following sql statements equivalent (eg in terms of performance)?
SELECT * FROM mytable where lastname IN(:lastnames);
SELECT * FROM mytable where lastname = :lastname;
Background: I have service that should serve a list, and a service that serves a single result. Now I thought why creating two database query endpoints, if I could achieve the same thing with just one query (means: also a single result could be queried by using the IN clause).
i tried it on my mariaDB database on a small table with hundred of records and the query with IN is a bit slower than the first one (which is to be expected) but we are talking of 0.02 sec difference
Assuming your db's engine is optimised and would check if there is one value inside the IN parameters and "convert" it to an equal/do the correct operation it would still be technically longer than just a written equal.
Also see this about IN performance.
Use This Query.
It May Be Solve Your Problem.
SELECT * FROM mytable where lastname IN(SELECT lastname FROM mytable where lastname = :lastname);
I am doing query on view with single predicates which gives me the record in 4-7 seconds, but when i try to retrieve the record with same predicate and directly with underlying query from that view it gives me records in less then seconds. I am using MySQL.
I have tried checking the execution plan of both the query and it gives major differences if i have hundreds of thousands of records in tables.
So any clue or idea why performance is better when using query directly?
Following is my view definition
SELECT entity_info.source_entity_info_id AS event_sync_id,
entity_info.source_system_id AS source_system_id,
entity_info.target_system_id AS destination_system_id,
event_sync_info.integrationid AS integration_id,
event_sync_info.source_update_time AS last_updated,
entity_info.source_internal_id AS source_entity_internal_id,
entity_info.source_entity_project AS source_entity_project,
entity_info.target_internal_id AS destination_entity_internal_id,
entity_info.destination_entity_project AS destination_entity_project,
entity_info.source_entity_type AS source_entity_type,
entity_info.destination_entity_type AS destination_entity_type,
event_sync_info.opshub_update_time AS opshub_update_time,
event_sync_info.entity_info_id AS entity_info_id,
entity_info.global_id AS global_id,
entity_info.target_entity_info_id AS target_entity_info_id,
entity_info.source_entity_info_id AS source_entity_info_id,
(
SELECT Count(0) AS count(*)
FROM ohrv_failed_event_view_count failed_event_view
WHERE ((
failed_event_view.integration_id = event_sync_info.integrationid)
AND (
failed_event_view.entityinfo = entity_info.source_entity_info_id))) AS no_of_failures
FROM (ohrv_entity_info entity_info
LEFT JOIN ohmt_eai_event_sync_info event_sync_info
ON ((
entity_info.source_entity_info_id = event_sync_info.entity_info_id)))
WHERE (
entity_info.source_entity_info_id IS NOT NULL)
Query examples
select * from view where integration_id=10
Execution plan of this processes 142668 rows for sub query that is there in this view
select QUERY_OF_VIEW and integration_id=10
Execution plan of this looks good and only required rows are getting processed.
I think the issue is in the following query:
SELECT * FROM view WHERE integration_id = 10;
This forces MySQL to materialize an intermediate table, against which it then has to query again to apply the restriction in the WHERE clause. On the other hand, in the second version:
SELECT (QUERY_OF_VIEW with WHERE integration_id = 10)
MySQL does not have to materialize anything other than the query in the view itself. That is, in your second version MySQL just has to execute the query in the view, without any subsequent subquery.
refereeing to this link of documentation you can see,that its depend on if the MERGE algorithm can used it will , but if its not applicable so new temp table must generated to find the relations of data, also you can see this answer that talking about optimization and when to use view and when you should not .
If the MERGE algorithm cannot be used, a temporary table must be used
instead. MERGE cannot be used if the view contains any of the
following constructs:
Aggregate functions (SUM(), MIN(), MAX(), COUNT(), and so forth)
DISTINCT
GROUP BY
HAVING
LIMIT
UNION or UNION ALL
Subquery in the select list
Refers only to literal values (in this case, there is no underlying
table)
I'm wondering if it's possible to store a result-set of a select query into a mysql variable, while using a stored procedure?
Example of a select query:
SELECT * FROM registrations WHERE user_id = <input_stored_proc>
I have multiple select queries that I'd like to run in that stored procedure and would like to store each result-set into a different variable.
What I'd like to do is, call that stored procedure from any application and be able to do something like this: (all SELECT queries require the user_id input)
CALL <stored_proc_name>(<user_id>)
And then use the variables, so I can e.g. loop through the rows of any executed select query.
Thanks.
I'm working through an SQL injection tutorial. I don't understand one aspect of an SQL statement which is used determine where the different columns in the table will be displayed on the web page and then used to execute statements. A previous SQL injection statement has been used to determine the number of columns in the table, which is 6. The SQL statement is
SELECT * FROM TableName Where id=12 union all select 1,2,3,4,5,6
I've researched the SELECT and UNION ALL statements and haven't been able to work out what is actually going on. My thinking is that the numbers in the 2nd select statement respresent the column numbers.
The second statement used to get the values from the table is:
SELECT * FROM TableName Where id=12 union all select 1,2,3,4,user(),6
What does the select 1,2,3,4,5,6 and select 1,2,3,4, user(),6 component of the SQL injection query actually do?
They are not column numbers but values. Assuming you can somehow inject the statement you now need something to do with it. The first example counts the columns. theUNION will fail when there are not enough columns. By adding more columns to the UNION eventually the statement will execute. Now you know how many columns there are.
The second one is injecting the user into the return result set. Assuming the result set gets displayed on the screen for some reason, you now have a user name (or service account name) with which to execute more statements on your database, escalate privileges or make service calls.
It's doing something like that. Without knowing more it's hard to know what exactly.
I have one table that has userID, department, er. I've created one simple query to gather all this information.
SELECT table.userID, table.department, table.er FROM table;
Now, I want to group all er's that belong to the same department and perform this calculation
select sum(table.er)/3 as department_er from table group by table.department;
Then add this result as a new column in my first query. To do this I've created a UDF that looks like this
BEGIN
DECLARE department_er FLOAT;
set department_er = (select sum(er) from table where table.department = dpt);
RETURN department_er;
END
Then I used that UDF in this query
SELECT table.userID, table.department, (select dptER(table.department)/3) as department_er FROM table
I've indexed my tables and more complex queries were dropped from 4+ minutes to less than 1 second. This seems to be pretty simple but is going on 10 minutes to run. Is there a better way to do this or a way to optimize my UDF?
Forgive my n00b-ness :)
Try a query without a dependent aggregated subquery in SELECT clause:
select table.userID,
table.department as dpt,
x.department_er
from table
join (
select department,
(sum(table.er)/3) As department_er
from table
group by department
) x
ON x.department = table.department
This UDF function cannot be optimized. Maybe it seems to work in simple queries, but generally it can hurt your database performance.
Imagine that we have a query like this one:
SELECT ....., UDF( some parameters )
FROM table
....
MySql must call this funcion for each record that is retrieved from the table in this query
If the table contains 1000 records - the function is fired 1000 times.
And the query within the function is also fired 1000 times.
If 10.000 records - then the function is called 10.000 times.
Even if you optimize this function in such a way, that the UDF will be 2 times faster, the above query will still fire the function 1000 times.
If 500 users have the same department - it still is called 500 times for each user and calculates the same value for each of them. 499 redundant calls, because only 1 call is required to calculate this value.
The only way to optimize such queries is to take the "inner" query out of the UDF function and combine it with the main query using joins etc.