2012-09-06 45 views
0

這MySQL查詢需要5分20秒,以執行服務表現滯後

SELECT PROVIDER, COUNT(DISTINCT(NAME)) FROM Test WHERE NAME NOT IN (SELECT NAME 
FROM Test WHERE OPERATION = 'SIGN_IN' and Test.CREATED_TIME BETWEEN UNIX_TIMESTAMP(CURRENT_DATE() - INTERVAL 1 DAY) * 1000 AND UNIX_TIMESTAMP(CURRENT_DATE()) * 1000) 
AND Test.CREATED_TIME BETWEEN UNIX_TIMESTAMP(CURRENT_DATE() - INTERVAL 1 DAY) * 1000 AND UNIX_TIMESTAMP(CURRENT_DATE()) * 1000 AND OPERATION='VALIDATE' GROUP BY PROVIDER; 

的解釋給出的結果

explain SELECT PROVIDER, COUNT(DISTINCT(NAME)) FROM Test WHERE NAME NOT IN 
(SELECT NAME FROM Test WHERE OPERATION = 'SIGN_IN' and Test.CREATED_TIME BETWEEN 
UNIX_TIMESTAMP(CURRENT_DATE() - INTERVAL 1 DAY) * 1000 AND UNIX_TIMESTAMP(CURRENT_DATE()) * 1000) AND   Test.CREATED_TIME BETWEEN UNIX_TIMESTAMP(CURRENT_DATE() - INTERVAL 1 DAY) * 1000 AND UNIX_TIMESTAMP(CURRENT_DATE()) * 1000 AND OPERATION='VALIDATE' GROUP BY PROVIDER; 
+----+--------------------+-----------------+----------------+----------------------------------------------------------------------+-------------------------+---------+------+--------+------------------------------------+ 
| id | select_type  | table   | type   | possible_keys              | key      | key_len | ref | rows | Extra        | 
+----+--------------------+-----------------+----------------+----------------------------------------------------------------------+-------------------------+---------+------+--------+------------------------------------+ 
| 1 | PRIMARY   | Test | ALL   | Test_CTndx,Test_CORndx       | NULL     | NULL | NULL | 137523 | Using where; Using filesort  | 
| 2 | DEPENDENT SUBQUERY | Test | index_subquery | Test_NAMEndx,Test_CTndx,Test_CORndx | Test_NAMEndx | 303  | func | 148 | Using where; Full scan on NULL key | 
+----+--------------------+-----------------+----------------+----------------------------------------------------------------------+-------------------------+---------+------+--------+------------------------------------+ 

的行數在表中爲50,000。

我該如何優化?

回答

1

重寫您的查詢來替換NOT IN與等效的NOT EXISTS語句應該更快。

例如,嘗試這樣的事情:

SELECT t1.PROVIDER, COUNT(DISTINCT(t1.NAME)) 
FROM Test t1 
WHERE t1.CREATED_TIME BETWEEN UNIX_TIMESTAMP(CURRENT_DATE() - INTERVAL 1 DAY) * 1000 AND UNIX_TIMESTAMP(CURRENT_DATE()) * 1000 
AND t1.OPERATION='VALIDATE' 
and NOT EXISTS (
    select null 
    from test t2 
    where t2.OPERATION = 'SIGN_IN' 
    and t2.CREATED_TIME BETWEEN UNIX_TIMESTAMP(CURRENT_DATE() - INTERVAL 1 DAY) * 1000 AND UNIX_TIMESTAMP(CURRENT_DATE()) * 1000 
    and t2.name = t1.name 
) 
GROUP BY t1.PROVIDER;