iT邦幫忙

1

[放棄了]MySQL 查詢語法執行卡住問題

  • 分享至 

  • xImage

抱歉,因為還有其他專案要忙,沒法在這卡太久,且不早點處理好同仁也沒法開發
也感謝大家讓我學到一些查詢語法及 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';
看更多先前的討論...收起先前的討論...
小哈片刻 iT邦研究生 5 級 ‧ 2022-10-14 03:59:33 檢舉
你要不要把時間加上單引號試試
select * from detail where AddDate >= '2022-10-11' and AddDate < '2022-10-12' and AID = '123456789' limit 100;
vicentli iT邦研究生 4 級 ‧ 2022-10-14 07:26:16 檢舉
啊,忘了打引號,實際是有加
select * from detailA (
select * from detail where AddDate '2022-10-11' between '2022-10-12' AS detailA ) where
detailA.AID = '123456789' and detailA.CID = '123456789' limit 100;
看看這樣有沒有比較好
個人猜沒有開全文檢索的關係吧,然後也沒說這各表有多大,假設1GB就好,你IOPS不夠,真的跑20分鐘都是有可能的
vicentli iT邦研究生 4 級 ‧ 2022-10-14 11:31:57 檢舉
謝謝 窮嘶發發發 跟 IOPS 或許也有關,我是掛透過 1G 網路掛 NAS NFS 雖然 NAS 多顆 HDD 做 RAID5,但我在其他專案有發現存取效能非常差。且早上來看這個表就包辦 11G 了
Albert iT邦高手 1 級 ‧ 2022-10-19 14:34:09 檢舉
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',

CID 沒有 INDEX
CID 是 int
你 where CID='文字串'
select * from detail where AID = '123456789' and CID = '123456789';
vicentli iT邦研究生 4 級 ‧ 2022-10-19 21:09:20 檢舉
抱歉手打失誤,CID 確實沒有 Index,但我在地端開發環境測試不搜 CID ,只搜 AID及 AddDate (有用 between) 組成 PK 來搜也是卡住,同語法在線上查看是會中索引,所以搜尋卡住應該不是沒中索引關係?
目前全清掉現在正常了
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
2
OuJiaHao
iT邦新手 4 級 ‧ 2022-10-14 00:31:12

雖然不知道你的問題錯在哪裡
但這邊有看到可以小小優化的地方
你時間區間的寫法改一下就可以透過 between 或是 (date1 >= date and date >= date2)
都會比你目前的 Query 好

vicentli iT邦研究生 4 級 ‧ 2022-10-14 09:07:58 檢舉

好的,我再改一下寫法,謝謝

2
wiseguy
iT邦超人 1 級 ‧ 2022-10-14 08:27:32

依照你的 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 會更好。

看更多先前的回應...收起先前的回應...
vicentli iT邦研究生 4 級 ‧ 2022-10-14 09:26:20 檢舉

謝謝,另一個同事是用 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';
wiseguy iT邦超人 1 級 ‧ 2022-10-14 10:31:49 檢舉

可以在 SQL 前面多加上 explain,會有一些資訊告訴你這條 SQL 有時麼問題
mysql explain用法和結果的含義

vicentli iT邦研究生 4 級 ‧ 2022-10-14 11:25:50 檢舉

謝謝,我放棄治療了,Truncate Table 也卡死,所以 Drop 掉重建重切 Partition 了,目前乾淨了正常。不過我也會試試調整 SQL 語法下 explain 看差異,感謝協助

vicentli iT邦研究生 4 級 ‧ 2022-10-14 12:53:34 檢舉

因地端開發環境清掉了,回報一下線上 CloudSQL explain 結果

EXPLAIN SELECT * FROM detail WHERE AID = '1665374410_1900023826048892017' AND AddDate >= '2022-10-10' AND AddDate < '2022-10-11';

https://ithelp.ithome.com.tw/upload/images/20221014/20094721eLhzXcc8Xt.jpg

EXPLAIN SELECT * FROM detail WHERE AddDate >= '2022-10-10' AND AddDate < '2022-10-11' AND  AID = '1665374410_1900023826048892017';

https://ithelp.ithome.com.tw/upload/images/20221014/20094721twpUInkh3f.jpg

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';

https://ithelp.ithome.com.tw/upload/images/20221014/200947216hDAfUyfKL.jpg

EXPLAIN SELECT * FROM detail WHERE AID = '1665374410_1900023826048892017';

https://ithelp.ithome.com.tw/upload/images/20221014/20094721nkCaudUrlf.jpg

0
ckp6250
iT邦好手 1 級 ‧ 2022-10-14 10:20:22

資料是幾筆呢?
隔空抓藥很難,若真要解決,去掉敏感資料,把table放上來,
測一下就知道了。

vicentli iT邦研究生 4 級 ‧ 2022-10-14 11:24:11 檢舉

早上來看這個 table 佔 11G
尷尬的是我下 count 要看一天筆數也卡死,所以決定放棄治療砍掉 table 了,感謝

ckp6250 iT邦好手 1 級 ‧ 2022-10-14 14:51:47 檢舉

下回若還遇到類似情形,
先 dump 出去,再 import 回來,
說不定也能變好。

vicentli iT邦研究生 4 級 ‧ 2022-10-14 15:55:02 檢舉

好,感謝您

我要發表回答

立即登入回答