Mysql

使用數千個整數優化 IN 子句

  • August 25, 2022

我有一個搜尋引擎,它輸出元素的 ID 以顯示在搜尋結果中,或在“分析”模組中使用。

在這一個中,我執行了許多不同的查詢以在儀表板中顯示見解。

SQL曾經是:

select {fields with calculations, max, count, whatever ...}
joining {with tables needed to join}
where {some wheres necessary for the query}
and element.id in (xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx ...)

問題是當“in 子句”包含超過 1000 個元素時。

SQL 查詢開始變慢(超過 1 秒)。

這些 ID 是整數,它們指的是主元素表的 PRIMARY KEY(整數)。

但是,正如我所說,當我必須在該子句中處理 2000 或 3000 個 id 時,查詢非常慢。

對性能有什麼想法嗎?

我考慮了一個帶有所有這些 ID 的臨時表(用於該儀表板頁面載入),並使用 JOIN 對充滿這些 ID 的臨時表執行所有查詢……但時間完全相同。

CREATE TEMPORARY TABLE my_temp_table (id INT NOT NULL PRIMARY KEY);
INSERT INTO my_temp_table VALUES (34), (45), (17321), (27320),... 6000 more ...

然後為其他查詢執行此表的聯接…

結果似乎更好,但是如果我有 10 個人訪問儀表板頁面,Mysql 將不得不處理 10 個臨時表……這對 Mysql Server 來說可以嗎?

是更好的解決方案嗎?

注意:我在 MySQL 8.0 中……我沒有“表值參數”(https://stackoverflow.com/a/33066869/311188

但是如果我有 10 個人訪問儀表板頁面,Mysql 將不得不處理 10 個臨時表……這對 Mysql Server 來說可以嗎? ” - 我不明白為什麼不,10 個臨時表並不多,並且使用臨時表 to JOINto 通常是過濾其他表的有效關係方式。該IN子句可能會導致性能問題(尤其是多個值),因為它相當於一堆OR語句。

由於您使用的是 MySQL 8,因此您可以嘗試在 JSON 數組上使用JSON_TABLEto 。JOIN

例如:

INNER JOIN JSON_TABLE(?, '$[*]' COLUMNS (id INT PATH '$')) AS t ON t.id = element.id

然後,您只需要將 ID 作為 JSON 數組傳遞(只有整數,只需將它們格式化為逗號分隔列表並放入

$$ $$可以在不需要 JSON 編碼器的情況下圍繞它們完成)。 這避免了必須手動創建臨時表。

它也適用於空列表,這與簡單IN (?)擴展不同,後者通常需要應用程序中的額外邏輯。

根據我的經驗,加入 JSON 數組JSON_TABLE通常比IN (...)使用 4 個元素更快。

引用自:https://dba.stackexchange.com/questions/316030