[英]MySQL - query fetching very slow
CREATE TABLE `offers` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`cap_id` varchar(255),
`deposit_value` varchar(255) default NULL,
`term` varchar(255) default NULL,
`annual_mileage` varchar(255) default NULL,
`finance_type` varchar(255) default NULL,
`monthly_payment` mediumint default NULL,
`stock` varchar(255) default NULL,
PRIMARY KEY (`id`)
) AUTO_INCREMENT=1;
INSERT INTO `offers` (`cap_id`,`deposit_value`,`term`,`annual_mileage`,`finance_type`,`monthly_payment`,`stock`) VALUES ("93897","6","24","12000","B",363,"0"),("90626","1","24","12000","P",810,"0"),("93607","6","36","25000","B",172,"1"),("35877","1","48","10000","B",678,"1"),("77134","3","24","10000","P",454,"0"),("47080","6","36","10000","B",737,"0"),("46392","3","24","30000","P",261,"0"),("21418","3","36","20000","B",390,"1"),("80175","9","48","10000","B",713,"1"),("91487","6","48","12000","P",778,"1");
INSERT INTO `offers` (`cap_id`,`deposit_value`,`term`,`annual_mileage`,`finance_type`,`monthly_payment`,`stock`) VALUES ("18311","9","24","20000","B",384,"0"),("41740","9","24","12000","P",674,"1"),("69030","9","24","10000","P",518,"0"),("53342","3","36","8000","B",746,"1"),("65566","6","36","30000","P",145,"1"),("63172","6","48","5000","P",698,"1"),("79712","1","48","30000","B",330,"1"),("90505","1","36","8000","B",458,"0"),("42393","1","36","20000","B",363,"1"),("70454","9","24","5000","B",673,"1");
INSERT INTO `offers` (`cap_id`,`deposit_value`,`term`,`annual_mileage`,`finance_type`,`monthly_payment`,`stock`) VALUES ("81215","1","48","8000","B",472,"0"),("76538","3","24","15000","B",226,"0"),("05094","9","36","12000","P",721,"1"),("57363","9","48","5000","B",777,"1"),("23233","1","48","12000","B",381,"0"),("40542","3","48","12000","P",610,"0"),("63824","3","24","12000","B",761,"1"),("17686","3","24","5000","P",893,"1"),("57669","9","48","30000","P",805,"0"),("21864","1","24","25000","P",530,"0");
INSERT INTO `offers` (`cap_id`,`deposit_value`,`term`,`annual_mileage`,`finance_type`,`monthly_payment`,`stock`) VALUES ("48360","3","48","12000","P",159,"0"),("88614","3","48","20000","B",730,"0"),("17693","1","24","10000","B",298,"0"),("34049","6","48","20000","B",728,"0"),("15038","9","24","10000","P",720,"1"),("31809","1","36","20000","P",237,"0"),("49277","9","48","25000","P",235,"1"),("54607","1","24","12000","P",661,"1"),("65098","1","48","20000","P",548,"1"),("76440","9","48","10000","P",495,"1");
CREATE TABLE `offers_lowest` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`date` DATE,
`cap_id` varchar(255),
`deposit` varchar(255) default NULL,
`term` varchar(255) default NULL,
`mileage` varchar(255) default NULL,
`finance_type` varchar(255) default NULL,
`lowest_price` mediumint default NULL,
`stock` varchar(255) default NULL,
PRIMARY KEY (`id`)
) AUTO_INCREMENT=1;
INSERT INTO `offers_lowest` (`date`,`cap_id`,`deposit`,`term`,`mileage`,`finance_type`,`lowest_price`,`stock`) VALUES ("2021-04-09","93897","6","24","12000","B",363,"0"),("2021-04-010","90626","1","24","12000","P",810,"0"),("2021-04-010","93607","6","36","25000","B",172,"1"),("2021-04-10","35877","1","48","10000","B",678,"1"),("2021-04-11","77134","3","24","10000","P",454,"0"),("2021-04-11","47080","6","36","10000","B",737,"0"),("2021-04-11","46392","3","24","30000","P",261,"0"),("2021-04-11","21418","3","36","20000","B",390,"1"),("2021-04-12","80175","9","48","10000","B",713,"1"),("2021-04-12","91487","6","48","12000","P",778,"1");
INSERT INTO `offers_lowest` (`date`,`cap_id`,`deposit`,`term`,`mileage`,`finance_type`,`lowest_price`,`stock`) VALUES ("2021-04-09","18311","9","24","20000","B",384,"0"),("2021-04-010","41740","9","24","12000","P",674,"1"),("2021-04-010","69030","9","24","10000","P",518,"0"),("2021-04-10","53342","3","36","8000","B",746,"1"),("2021-04-11","65566","6","36","30000","P",145,"1"),("2021-04-11","63172","6","48","5000","P",698,"1"),("2021-04-11","79712","1","48","30000","B",330,"1"),("2021-04-11","90505","1","36","8000","B",458,"0"),("2021-04-12","42393","1","36","20000","B",363,"1"),("2021-04-12","70454","9","24","5000","B",673,"1");
INSERT INTO `offers_lowest` (`date`,`cap_id`,`deposit`,`term`,`mileage`,`finance_type`,`lowest_price`,`stock`) VALUES ("2021-04-09","81215","1","48","8000","B",472,"0"),("2021-04-09","76538","3","24","15000","B",226,"0"),("2021-04-010","05094","9","36","12000","P",721,"1"),("2021-04-10","57363","9","48","5000","B",777,"1"),("2021-04-11","23233","1","48","12000","B",381,"0"),("2021-04-11","40542","3","48","12000","P",610,"0"),("2021-04-11","63824","3","24","12000","B",761,"1"),("2021-04-11","17686","3","24","5000","P",893,"1"),("2021-04-12","57669","9","48","30000","P",805,"0"),("2021-04-12","21864","1","24","25000","P",530,"0");
INSERT INTO `offers_lowest` (`date`,`cap_id`,`deposit`,`term`,`mileage`,`finance_type`,`lowest_price`,`stock`) VALUES ("2021-04-09","48360","3","48","12000","P",159,"0"),("2021-04-09","88614","3","48","20000","B",730,"0"),("2021-04-010","17693","1","24","10000","B",298,"0"),("2021-04-10","34049","6","48","20000","B",728,"0"),("2021-04-11","15038","9","24","10000","P",720,"1"),("2021-04-11","31809","1","36","20000","P",237,"0"),("2021-04-11","49277","9","48","25000","P",235,"1"),("2021-04-11","54607","1","24","12000","P",661,"1"),("2021-04-12","65098","1","48","20000","P",548,"1"),("2021-04-12","76440","9","48","10000","P",495,"1");
CREATE INDEX idx_profile_grouping ON offers (cap_id, deposit_value, term, annual_mileage);
CREATE INDEX idx_specials_query ON offers_lowest (cap_id, deposit, term, mileage);
所以,我正在嘗試加入兩個表 - 一個是我們平台上的活動報價列表(我們是一個汽車租賃比較網站),另一個是自定義表,它每天記錄每輛車的最佳價格(cap_id),以及每個可能的財務狀況,即 9 個月的存款價值、24 個月的合同和每年 8,000 英里等。
這是為了確定什么是“好”價格的最終目標,output 包含MIN(offers.monthly_payment)
和MIN(offers_lowest.lowest_price)
以及計算的百分比差異,歷史價格數據取自 7 -day 日期范圍不包括當天。
offers_lowest
是從每天的offers
中匯總的,找到按以下條件分組的最低monthly_payment
付款: cap_id, deposit_value, term, annual_mileage, finance_type
到目前為止,這是我想出的:
SELECT
s.cap_id,
s.deposit,
s.term,
s.mileage,
s.best_price,
f.previous_best,
(( s.best_price - f.previous_best ) / f.previous_best ) * 100 AS difference,
s.stock
FROM
(SELECT
o.cap_id,
o.deposit_value as deposit,
o.term,
o.annual_mileage as mileage,
o.finance_type,
MIN(o.monthly_payment) AS best_price,
o.stock,
o.brand_id
FROM
offers o USE INDEX(idx_profile_grouping)
WHERE o.finance_type = 'P'
GROUP BY o.cap_id, o.deposit_value, o.term, o.annual_mileage
) s
INNER JOIN
(SELECT
ol.cap_id,
ol.deposit,
ol.term,
ol.mileage,
MIN(lowest_price) as previous_best
FROM
offers_lowest ol USE INDEX(idx_specials_query)
WHERE finance_type = 'P'
AND ol.date > CURDATE() - INTERVAL 7 DAY
AND ol.date <= CURDATE() - INTERVAL 1 DAY
GROUP BY ol.cap_id, ol.deposit, ol.term, ol.mileage
) f ON s.cap_id = f.cap_id AND s.deposit = f.deposit AND s.term = f.term AND s.mileage = f.mileage
GROUP BY s.cap_id, s.deposit, s.term, s.mileage
問題在於速度。 當我單獨運行任一子查詢時,運行時間 <0.1 秒,然后獲取大約 75 秒。 當我運行整個過程時,它會一直運行直到我停止它(>10 分鍾)。
這些索引是我在 cap_id、deposit、term 和 mileage 字段(兩個表)上創建的,以試圖加快速度。
解釋返回這個:
# ID | 選擇類型 | 桌子 | 分區 | 類型 | 可能的鍵 | 鑰匙 | key_len | 參考 | 行 | 過濾 | 額外的 |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 基本的 | 全部 | 965741 | 100.00 | 使用哪里; 使用臨時的; 使用文件排序 | ||||||
1 | 基本的 | 參考 | <auto_key0> | <auto_key0> | 10 | f.cap_id | f.存款 | f.術語 | f.里程 | ||
3 | 衍生的 | 奧爾 | 指數 | idx_specials_query | idx_specials_query | 13 | 17386818 | 5.55 | 使用哪里 | ||
2 | 衍生的 | ○ | 指數 | idx_profile_grouping | idx_profile_grouping | 10 | 4800964 | 50.00 | 使用哪里 |
並且 SHOW PROFILE 返回這個:
地位 | 期間 |
---|---|
開始 | 0.000017 |
檢查查詢緩存以進行查詢 | 0.000171 |
檢查權限 | 0.000006 |
檢查權限 | 0.000005 |
打開表 | 0.000020 |
在里面 | 0.000109 |
系統鎖 | 0.000009 |
優化 | 0.000005 |
優化 | 0.000011 |
統計數據 | 0.000033 |
准備 | 0.000037 |
排序結果 | 0.000007 |
優化 | 0.000015 |
統計數據 | 0.000017 |
准備 | 0.000017 |
排序結果 | 0.000012 |
統計數據 | 0.000046 |
准備 | 0.000021 |
創建 tmp 表 | 0.000020 |
排序結果 | 0.000007 |
執行 | 0.000013 |
發送數據 | 0.000012 |
執行 | 0.000004 |
發送數據 | 68.205032 |
將 HEAP 轉換為磁盤 | 0.542756 |
發送數據 | 3.132642 |
執行 | 0.000019 |
發送數據 | 7.968966 |
將 HEAP 轉換為磁盤 | 0.746200 |
發送數據 | 22.506716 |
將 HEAP 轉換為磁盤 | 0.567816 |
發送數據 | 4.886870 |
創建排序索引 | 2.151519 |
結尾 | 0.000019 |
查詢結束 | 0.000010 |
刪除 tmp 表 | 0.002051 |
查詢結束 | 0.000019 |
收盤 | 0.000005 |
刪除 tmp 表 | 0.001385 |
收盤 | 0.000009 |
刪除 tmp 表 | 0.002780 |
收盤 | 0.000017 |
釋放物品 | 0.000069 |
清理干凈 | 0.000007 |
打掃干凈 | 0.000021 |
由此看來,我還沒有寫出最有效的查詢..
我們使用 AWS RDS 實例,運行 MySQL 5.7.12。
如果我可以提供任何其他內容來添加背景,請告訴我。
FROM ( SELECT... ) JOIN ( SELECT... )
效率低下。 嘗試將其中至少一個移到外部SELECT
中。 (如果您為JOIN
添加合適的索引,這可能會消除“創建排序索引”。它也可能會消除大多數神秘的“發送數據”。)GROUP BY
是不合適的,因為它沒有說明為 stock 或 brand_id 賦予哪個值。 如有必要,在找到信息的 rest 后,通過額外的JOIN
獲取它們。offers_lowest
需求INDEX(finance_type, date)
USE INDEX...
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.