mysql 5.7+查詢的select語句中IFNULL的性能成本是多少
我最近對我的 Web 伺服器在服務請求時執行的 mysql 查詢進行了升級。查詢有兩種主要排列方式,一種通常限制為返回 500 行,另一種限制為列的特定值(並且已正確索引),從而產生 5-10k 的結果。
原始查詢看起來像這樣……
SELECT v1, v2, v3 FROM t1;
新查詢如下所示。
SELECT v1, v2, v3, IFNULL(t2.u1, 0), IFNULL(t2.u2, '') FROM t1 LEFT JOIN t2 ON t1.id = t2.id;
更改查詢會導致我的數據庫連接最大化,並隨後使我的大多數 Web 伺服器請求超時。
另請注意,
t2
目前為空,因此IFNULL
應該將 every 解析為第二個參數。主要問題 a.)
IFNULL
價格昂貴 b.) 它是否會以某種方式阻止查詢的有效記憶體?
讓我們看看這個成本列表:
- 聲明的成本
- 連續成本
- 函式的成本
這些是從成本最大的開始。也就是說,函式成本在大局中是微不足道的;別擔心。
另請參閱
COALESCE()
。記憶體
使用 Engine=InnoDB,主記憶體是“buffer_pool”;
innodb_buffer_pool_size
應該是可用 RAM 的 70% 左右。 對行的所有操作都發生在 buffer_pool 中:
- 從磁碟讀取塊(如果尚未在記憶體中)
- 查找塊中的行
- 獲取 (SELECT) 或修改行
- 最終將塊寫回磁碟(如果已修改)
由於您在詢問
SELECT
,因此只有步驟 1、2、3 是相關的。此外,如果您繼續選擇同一行(或附近的行),則不會重複第 1 步。注意:這裡沒有提到函式呼叫的任何影響。
注意:在冷系統上(記憶體中沒有任何內容),
SELECT
由於第 1 步,第一個會更慢。之後相同或“相似”的查詢會更快(有時快 10 倍)。評論:
ON t1.id = t2.id
你有兩張相同的桌子PRIMARY KEYS
嗎?為什麼?在 JOIN 中獲得良好性能的主要方法是擁有合適的索引。讓我們看看真正的查詢和
SHOW CREATE TABLE
正在加入的表。評論中提到的 BNL 是一種內部“記憶體”,用於加速某些連接。你幾乎無法控制它的使用。它指的是從輔助表中獲取所需的所有內容並將其儲存在記憶體中的雜湊中。它僅適用於加入時。不涉及函式呼叫(在您的範例中)。
ON
如果在or中使用了函式(例如,IFNULL)WHERE
,則可能會阻止使用其他合適的索引。(cf 不是“sargable”)