有一張表,資料量很大,大概5G左右
現在有一個很簡單的sql,類似下面的陳述句
SELECT
col_name, SUM(count) AS value
FROM
table_name
WHERE
sys_date BETWEEN '2017-10-01' AND '2017-10-31'
GROUP BY col_name
ORDER BY value DESC
是不是很簡單,執行時間大概50秒
但是我換一種寫法,先通過where得到一個結果集,然后在這結果集上做一次group by
SELECT col_name, SUM(count) AS value
FROM
(
SELECT
col_name, count
FROM
table_name
WHERE
sys_date BETWEEN '2017-10-01' AND '2017-10-31'
) A
GROUP BY col_name
ORDER BY value DESC
這樣的執行結果只有4秒
為什么會是這樣?
Group BY 不是作用在where的結果集上的嗎?但是我感覺第一個sql的執行順序并不是這樣,不然,兩個類似的SQL為什么差別這么大?
PS:
explain的結果沒什么太大的差別,索引都沒有用到
uj5u.com熱心網友回復:
看一下EXPLAIN SELECT有什么不同。uj5u.com熱心網友回復:
還是要仔細看看explain看有沒有什么差別的地方沒有發現uj5u.com熱心網友回復:
比較一下兩個return的資料是否一樣,然后看 explain selectuj5u.com熱心網友回復:
這是第一個的explain
"id" "select_type" "table" "type" "possible_keys" "key" "key_len" "ref" "rows" "Extra"
"1" "PRIMARY" "<derived2>" "ALL" \N \N \N \N "2576336" "Using temporary; Using filesort"
"1" "PRIMARY" "category_mapping" "ALL" \N \N \N \N "148" "Using where; Using join buffer (Block Nested Loop)"
"2" "DERIVED" "path_rule" "index" "INDEX_APPS,INDEX_APPS_WEEK" "INDEX_APPS" "306" \N "5152673" "Using where; Using temporary; Using filesort"
這是第二個的
"id" "select_type" "table" "type" "possible_keys" "key" "key_len" "ref" "rows" "Extra"
"1" "PRIMARY" "<derived2>" "ALL" \N \N \N \N "2576336" \N
"1" "PRIMARY" "category_mapping" "ALL" \N \N \N \N "148" "Using where; Using join buffer (Block Nested Loop)"
"2" "DERIVED" "<derived3>" "ALL" \N \N \N \N "2576336" "Using temporary; Using filesort"
"3" "DERIVED" "path_rule" "ALL" "INDEX_APPS,INDEX_APPS_WEEK" \N \N \N "5152673" "Using where"
uj5u.com熱心網友回復:
explain 對比下執行計劃如果 table_name 是表, 理論上這兩個的執行計劃應該是一樣的, 如果是查詢 VIEW,那另當別論
如果對比執行計劃確定是一樣的話,那么可能是快取,你可以多次執行對比下效率
uj5u.com熱心網友回復:
條件列上沒有索引 ? 對比執行計劃,兩個執行計劃,一個走了索引,另一個沒有,但是搜索的記錄數都一樣,所以第一個查詢的索引應該不是條件上的索引然后看執行計劃的 Extra,不知道樓主用的什么版本,具體的查詢和表結構是什么
按照你寫的查詢,只有一個條件,但里面 Extra 里面出現了兩次 WHERE , 第一個查詢還出現了兩次 sort
正常的單表應該是一次 WHERE + 一次 SORT
(我在 5.7 版本上,童瑤查詢模擬驗證了一下,兩種寫法執行計劃一樣,只會有一條執行計劃)
uj5u.com熱心網友回復:
樓主的真實SQL陳述句是什么?uj5u.com熱心網友回復:
第一個SQL(慢)
EXPLAIN
SELECT
A.execute_app AS name, IFNULL(category_mapping.view_name, execute_app) AS mappingName
FROM
(
SELECT
sys_date,
month_number,
execute_app, SUM(COUNT) AS value
FROM path_rule
WHERE month_number=10 AND YEAR = 2017)) AND execute_app IS NOT NULL AND LENGTH(execute_app) > 0
GROUP BY execute_app
ORDER BY value DESC)A
LEFT JOIN
category_mapping ON
A.execute_app = category_mapping.log_name AND category_mapping.kpi_name = 'path_rule_app'
ORDER BY A.value DESC
LIMIT 10
第二個SQL, group by 放外面的(快)
EXPLAIN
SELECT
A.execute_app AS name, IFNULL(category_mapping.view_name, execute_app) AS mappingName
FROM
(
SELECT execute_app, SUM(COUNT) AS value
FROM(
SELECT execute_app, COUNT
FROM
path_rule
WHERE month_number = 10 AND YEAR = 2017 AND execute_app IS NOT NULL AND LENGTH(execute_app) > 0 ) r
GROUP BY execute_app
ORDER BY value DESC)A
LEFT JOIN
category_mapping ON
A.execute_app = category_mapping.log_name AND category_mapping.kpi_name = 'path_rule_app'
LIMIT 10
Explain的結果上面貼過了
uj5u.com熱心網友回復:
上面第一個SQL中11行多了兩個括號uj5u.com熱心網友回復:
第一個查詢最后面多了一句ORDER BY A.value DESC
你把第2個查詢加上這個再測驗一下
uj5u.com熱心網友回復:
你第一個sql陳述句用了子查詢,索引會失效,所以時間長uj5u.com熱心網友回復:
第一個50秒,第二個4秒。在執行完第二個以后,馬上執行第一個看,看看需要多長時間。
uj5u.com熱心網友回復:
快取初次執行與執行幾次效率會有很大差距 試試換一下順序轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/89493.html
標籤:MySQL
上一篇:DB2 9.5版本 自定義函式怎么實作字串的四則運算!!!!
下一篇:mysql sql優化
