抱歉,因為還有其他專案要忙,沒法在這卡太久,且不早點處理好同仁也沒法開發
也感謝大家讓我學到一些查詢語法及 explain 查看
早上來看這個表就佔 11G,所以應該是太大,現在砍掉重練了且加上了 partition。
確實儲存放 NAS NFS 之前就發現 IOPS 不太好,主要可能多個服務在用,網路也沒規劃好,但那是別單位管的動不了。
原問題如下
工作上 MySQL 開發環境查詢碰到一種奇怪狀況,先說明一下環境
MySQL 5.7 用 Kubernetes 起的,my.cnf 設定全官方預設
給的 CPU RAM 記得是 4C、4G 以上,沒有做主從。硬碟掛 NAS NFS 用量約11G
主要問題,當我進 POD 測試以下語法時,可以順利撈取時間區間資料
select * from detail where AddDate >= "2022-10-11" and AddDate < "2022-10-12 limit 100;
但當我多加一個 AID 條件
select * from detail where AddDate >= "2022-10-11" and AddDate < "2022-10-12" and AID = '123456789' limit 100;
或者改加一個 CID 條件
select * from detail where AddDate >= "2022-10-11" and AddDate < "2022-10-12" and CID = '123456789' limit 100;
或者兩個條件都加
select * from detail where AddDate >= "2022-10-11" and AddDate < "2022-10-12" and AID = '123456789' and CID = '123456789' limit 100;
查詢就會卡住了,卡幾十分鐘只好 kill 掉,有查詢過資料庫並沒有任何因讀寫鎖表情況
CloudSQL 5.7 測試及正式環境都沒有問題,且 CloudSQL CPU/RAM 規格更小、資料量更大,只是硬碟是有比較快,但下的語法查詢範圍更大卻很快就出來。
上述範例查詢條件有 AddDate 及 limit 是因為出問題,刻意加入為了縮小範圍測試看看,這是實際線上在跑的。
select * from detail where AID = '123456789' and CID = '123456789';
不明所以,不曉得有沒前輩碰過這種狀況,感謝
以下結構有改掉命名及拿掉7個欄位,僅供參考,但主鍵有列出來
CREATE TABLE IF NOT EXISTS `detail` (
`AID` varchar (50) NOT NULL DEFAULT '0',
`BID` varchar(25) NOT NULL DEFAULT '0',
`CID` int(11) NOT NULL DEFAULT '0',
`Level` int(11) NOT NULL DEFAULT '0',
`EID` varchar(75) NOT NULL DEFAULT '',
`EType` int(11) NOT NULL DEFAULT '0',
`Price` varchar(50) NOT NULL DEFAULT '',
`ATotal` decimal(18,6) NOT NULL DEFAULT '0.000000',
`BTotal` decimal(18,6) NOT NULL DEFAULT '0.000000'',
`Qty` decimal(18,6) NOT NULL DEFAULT '0.000000',
`Product` varchar(25) NOT NULL DEFAULT '',
`AddDate` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY (`AID`,`AddDate`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
嘗試改用 between 卡住
select * from detail where AID = '2205015480956298192' and AddDate between '2022-10-11 00:00:00.000' and '2022-10-11 23:59:59.999';
雖然不知道你的問題錯在哪裡
但這邊有看到可以小小優化的地方
你時間區間的寫法改一下就可以透過 between 或是 (date1 >= date and date >= date2)
都會比你目前的 Query 好
依照你的 primary key 來看,順序跟你的 where 排列相反,所以沒用到 primary key,而且又放了日期區間,所以你的 SQL 是在做全 table 掃描,才會非常久。
可以先試試調整一下 where 改成:
select * from detail where AID = '123456789' and AddDate >= "2022-10-11" and AddDate < "2022-10-12" limit 100;
如果效果不彰,那應該是因為日期有不等式,所以 primary key 還是派不上用場。改為 OuJiaHao 所說的 between 會更好。
謝謝,另一個同事是用 between 寫,只是沒解決,我為了方便寫改用 >= < '日期',原來會影響。嘗試改寫如下,卡住。
select * from detail where AID = '2205015480956298192' and AddDate between '2022-10-11 00:00:00.000' and '2022-10-11 23:59:59.999';
可以在 SQL 前面多加上 explain,會有一些資訊告訴你這條 SQL 有時麼問題
mysql explain用法和結果的含義
謝謝,我放棄治療了,Truncate Table 也卡死,所以 Drop 掉重建重切 Partition 了,目前乾淨了正常。不過我也會試試調整 SQL 語法下 explain 看差異,感謝協助
因地端開發環境清掉了,回報一下線上 CloudSQL explain 結果
EXPLAIN SELECT * FROM detail WHERE AID = '1665374410_1900023826048892017' AND AddDate >= '2022-10-10' AND AddDate < '2022-10-11';
EXPLAIN SELECT * FROM detail WHERE AddDate >= '2022-10-10' AND AddDate < '2022-10-11' AND AID = '1665374410_1900023826048892017';
EXPLAIN SELECT * FROM detail WHERE AID = '1665374410_1900023826048892017' AND AddDate BETWEEN '2022-10-10 00:00:00.000' AND '2022-10-11 00:00:00.000';
EXPLAIN SELECT * FROM detail WHERE AID = '1665374410_1900023826048892017';
資料是幾筆呢?
隔空抓藥很難,若真要解決,去掉敏感資料,把table放上來,
測一下就知道了。