count(*) 真的很貴嗎?
我有一個頁面,其中有 4 個選項卡,顯示基於不同表格的 4 個不同報告。
我使用
select count(*) from <table>查詢獲取每個表的行數,並在選項卡上顯示每個表中可用的行數。結果,每個頁面回發導致count(*)執行 5 個查詢(4 個用於獲取計數,1 個用於分頁)和 1 個用於獲取報告內容的查詢。現在我的問題是:
count(*)查詢真的很昂貴嗎——我應該將行數(至少是那些顯示在選項卡上的行數)保持在頁面的視圖狀態而不是多次查詢嗎?COUNT(*) 查詢的成本是多少?
您需要附加SQL Profiler或L2SProf 之類的應用程序級別分析器,然後在您的上下文中查看實際查詢成本:
- 猜測問題是什麼並嘗試確定潛在解決方案的可能好處
- 允許其他人在 da 網際網路上為您猜測 - 有很多沒有引用的錯誤資訊,包括在這個執行緒中(但不在這篇文章中:P)
完成後,您將清楚最好的方法是什麼 - 即 SELECT COUNT 是否占主導地位,等等。
完成此操作後,您還將知道您選擇做的任何更改是否產生了積極或消極的影響。
一般來說,成本
COUNT(*)成本與滿足查詢條件的記錄數加上準備這些記錄所需的時間成正比(這取決於底層查詢的複雜性)。在處理單個表的簡單情況下,通常會進行特定的優化以使此類操作變得便宜。例如,
COUNT(*)沒有WHERE條件從單個MyISAM表中執行MySQL- 這是即時的,因為它儲存在元數據中。例如,讓我們考慮兩個查詢:
SELECT COUNT(*) FROM largeTableA a由於每條記錄都滿足查詢,因此
COUNT(*)成本與表中的記錄數成正比(即,與它返回的內容成正比)(假設它需要訪問行並且沒有特定的優化來處理它)SELECT COUNT(*) FROM largeTableA a JOIN largeTableB b ON a.id = b.id在這種情況下,引擎很可能會使用
HASH JOIN,執行計劃將是這樣的:
- 在較小的表上建構雜湊表
- 掃描較大的表,在雜湊表中查找每條記錄
- 在比賽進行時數數比賽。
在這種情況下,
COUNT(*)成本(第 3 步)可以忽略不計,查詢時間將完全由第 1 步和第 2 步定義,即建構雜湊表並進行查找。對於這樣的查詢,時間將是O(a + b):它並不真正取決於匹配的數量。
a.id但是,如果和上都有索引b.id,則MERGE JOIN可以選擇 並且COUNT(*)時間將再次與匹配次數成正比,因為每次匹配後都會執行索引查找。