Subselect bad performance - mysql

This is my query, it takes a long time to execute. Can I use an inner join? I am working on only one table.
SELECT imei,csv_data_table.time,phone_model,test_unique_id
FROM verveba_mos.csv_data_table
WHERE time = (SELECT MAX(time) FROM csv_data_table
T1 WHERE csv_data_table.imei=T1.imei)

You can use JOIN or NOT EXISTS() to do this, that doesn't necessarily means it will be faster:
EXISTS() :
SELECT imei,csv_data_table.time,phone_model,test_unique_id
FROM verveba_mos.csv_data_table t
WHERE NOT EXISTS(SELECT 1
FROM csv_data_table s
WHERE t.imei= s.imei
AND s.time > t.time)
JOIN:
SELECT t.imei,t.time,t.phone_model,t.test_unique_id
FROM verveba_mos.csv_data_table t
JOIN(SELECT s.imei,MAX(time) as max_t
FROM csv_data_table s
GROUP BY s.imei) p
ON(t.imei= p.imei and t.time = p.max_t)

SELECT t1.imei, t1.time, t1.phone_model, t1.test_unique_id
FROM csv_data_table t1
JOIN (select imei, max(time) time from csv_data_table group by imei) t2
ON (t1.imei = t2.imei and t1.time = t2.time)
You should also consider putting an index on csv_data_table(imei, time) if you don't already have one.

Related

Join with column outside subquery

SELECT t1.name as r_name, t1.values as r_values
FROM table as t1
JOIN (
SELECT SUM(amount) as amount
FROM database2.table
WHERE ids IN (t1.values)
) as t2
WHERE t1.id = 20;
I get an error, that t1.values inside the subquery is unknown column.
You need to rewrite your query and take inne where to join condition:
SELECT t1.name as r_name, t1.values as r_values
FROM table as t1
JOIN (
SELECT SUM(amount) as amount
FROM database2.table
) as t2 ON t2.ids = t1.values
WHERE t1.id = 20;
Also, you don't use amount column, so what is the point of join?
Another issue, you don't have any join condition defined.
I think you need to read about joins in SQL first :)
It seems you are trying to join database2.table to your t1 based on t1.values list.
I added group by IDs in t2 since your using aggregation function. Then, not sure what's the purpose of your sum(amount)
SELECT t1.name as r_name, t1.values as r_values
FROM table as t1
JOIN (
SELECT SUM(amount) as amount, ids
FROM database2.table
GROUP BY ids
) as t2 on t2.ids IN (t1.values)
WHERE t1.id = 20;

MySQL UPDATE with subqueries and join

Hi i am new to subqueries and so not sure if i am doing right
I am happy with this
SELECT t2.cons, t1.date, t1.account_no FROM
(
SELECT date, account_no FROM tbl_consignment_x3
) t1
INNER JOIN
(
SELECT cons, date, account_no FROM
tbl_volume_analysis
) t2
ON t2.account_no=t1.account_no AND t2.date=t1.date
It gives me the results i want to use
So i was hoping something like this below would do what i want but i can't get the syntax right plus i'm not sure if my technique is completely wrong
UPDATE tbl_margin_all t3
(
SELECT t2.cons, t1.date, t1.account_no FROM
(
SELECT date, account_no FROM tbl_consignment_x3
) t1
INNER JOIN
(
SELECT cons, date, account_no FROM
tbl_volume_analysis
) t2
ON t2.account_no=t1.account_no AND t2.date=t1.date
)
SET t3.cons=t2.cons
WHERE t1.date=t3.date AND t1.account_no=t3.account_no
thanks
ADDITION:
First i do a total count of consignments for a particular date taken from consignment table that is then written in volume table with the date and account.. then from consignments table i want to write to each consignment that count that i did.
You need to join with the first subquery -- put JOIN after t3.
Actually, you don't need any of the subqueries at all, you can just join directly with the tables.
UPDATE tbl_margin_all AS t3
JOIN tbl_consignment_x3 AS t1 ON t1.date = t3.date AND t1.account_no=t3.account_no
JOIN tbl_volume_analysis AS t2 ON t2.account_no=t1.account_no AND t2.date=t1.date
SET t3.cons = t2.cons
It's the same in the SELECT query, it should be:
SELECT t2.cons, t1.date, t1.account_no
FROM tbl_consignment_x3 AS t1
JOIN tbl_volume_analysis AS t2
ON t2.account_no=t1.account_no AND t2.date=t1.date
Notice the comma after t3 for syntax
UPDATE tbl_margin_all_4000 t3,
(
SELECT cons, t1.date, t1.account_no FROM
(
SELECT date, account_no, consignment_no FROM tbl_consignment_x3_4000
) t1
INNER JOIN
(
SELECT cons, date, account_no FROM
tbl_volume_analysis_4000
) t2
ON t2.account_no=t1.account_no AND t2.date=t1.date
) as src
SET t3.cons=src.cons
WHERE t3.date=src.date AND t3.account_no=src.account_no
this query took 4 mins. i had tried the double joins as suggested kindly but that took 45 mins.

MYSQL Performance Tuning with group by clause

I have a query like this.
SELECT count(*)
FROM table1 e
WHERE e.column1=1
AND e.id IN
(SELECT MAX(ID)
FROM table2 A
WHERE A.column1=1
AND A.date=CURDATE()
GROUP BY A.column2);
When I run this query it is taking too much of time as I am having thousands of records. How can I tune the query to perform better.
Thanks in advance.
EDIT: column2 in table2 is id of Table1
Change in (. . .) To use join instead. Like
SELECT count(*)
FROM table1 AS e
Inner join
(
SELECT MAX(ID)
FROM table2 A
WHERE A.column1 = 1
AND A.date = CURDATE()
GROUP BY A.column2
) t2 on e.id = t2.id
WHERE e.column1 = 1
Maybe:
SELECT count(*)
FROM table1 e
WHERE e.column1=1
AND EXISTS
(SELECT *
FROM table2 A
WHERE A.column1=1
AND A.date=CURDATE()
AND A.ID = e.id);

Better solution for finding unique visitors

I am using the following query for finding the number of unique visitors from one of my table for each day. But this is affecting the performance. Can anyone suggest a better solution for this. My current query is :
SELECT t.date,COUNT(DISTINCT t.uID) as unique_clicks FROM table_name t
WHERE
NOT EXISTS(
SELECT 1
FROM table_name t2
WHERE
t2.uID = t.uID
AND t2.date < (t.date)
)
GROUP BY t.date
You could try this:
SELECT
t.date, COUNT(DISTINCT t.uID) as unique_clicks
FROM
table_name t LEFT JOIN table_name t1
ON t.uID=t2.uID AND t2.date < t.date
WHERE
t2.uID is NULL
GROUP BY t.date
I think that a join should be faster than an EXISTS clause in this particular situation. Or if I understand the logic correctly, also this:
SELECT min_date, COUNT(*) as unique_clicks
FROM (
SELECT
t.uID, min(t.date) min_date
FROM
table_name t
GROUP BY
t.uID
) s
GROUP BY min_date
Please see fiddle here.

sql script works on MySQL, but not on google bigquery

I have sql scripts that work fine in MySQL, but that I cannot get to work in google bigquery. After reading through bq documentation, I made a number of adjustments (eg no more than one join per select statement), but the script still fails. Any help is appreciated. If you know of any good resources in terms of bq sql vs other sql, that would also be greatly appreciated. Thanks.
SELECT
T1.action_date AS action_date,
T1.ad_campaign_category AS ad_campaign_category,
T1.campaign_id AS campaign_id,
T2.total_sends AS total_sends,
count(*) AS clicks_per_category
FROM (
SELECT action_date, campaign_id, ad_campaign_category
FROM projectX.email_action
WHERE action_date > '2009-04-01' AND action_date < '2011-05-01') T1,
(
SELECT action_date, campaign_id, ad_campaign_category, count(*) AS total_sends
FROM projectX.email_action
WHERE action_type = 'send' AND action_date > '2009-04-01' AND action_date < '2011-05-01'
GROUP BY action_date, campaign_id) T2
WHERE T1.action_date = T2.action_date
AND T1.campaign_id = T2.campaign_id
GROUP BY action_date, campaign_id, ad_campaign_category
The JOIN must be explicit -- that is, rather than using SELECT ... FROM (...) t1, (...) t2 WHERE t1.x = t2.y you should use the form SELECT ... FROM (...) t1 JOIN (...) t2 ON t1.x = t2.y
For your example, this would look like:
SELECT
T1.action_date AS action_date,
T1.ad_campaign_category AS ad_campaign_category,
T1.campaign_id AS campaign_id,
T2.total_sends AS total_sends,
count(*) AS clicks_per_category
FROM (
SELECT action_date, campaign_id, ad_campaign_category
FROM projectX.email_action
WHERE action_date > '2009-04-01' AND action_date < '2011-05-01') T1
JOIN (
SELECT action_date, campaign_id, ad_campaign_category, count(*) AS total_sends
FROM projectX.email_action
WHERE action_type = 'send' AND action_date > '2009-04-01' AND action_date < '2011-05-01'
GROUP BY action_date, campaign_id) T2
ON T1.action_date = T2.action_date
AND T1.campaign_id = T2.campaign_id
GROUP BY action_date, campaign_id, ad_campaign_category
Note if you get an error that one of the tables is too large, try using JOIN EACH instead of JOIN.