Asp.net
計算列中不同值(包括 NULL 值)的最快方法
Transact-Sql Count Distinct操作對列中的所有非空值進行計數。我需要計算一組表中每列的不同值的數量,包括空值(因此,如果列中有空值,則結果應該是
(Select Count(Distinct COLNAME) From TABLE) + 1.這將在數據庫中每個表的每一列上重複。包括數百個表,其中一些表超過 1M 行。因為這需要在每一列上完成,所以為每一列添加索引不是一個好的選擇。
這將作為 ASP.net 站點的一部分完成,因此與程式碼邏輯的集成也可以(即:這不必作為一個查詢的一部分完成,但如果可以以良好的性能完成,那麼即使更好的)。
最有效的方法是什麼?
測試後更新
我從一個很好的代表性表格上給出的答案中測試了不同的方法。該表有 320 萬條記錄,幾十列(少數有索引,大多數沒有)。一列有 320 萬個唯一值。其他列的範圍從所有 Null(一個值)到最多 40K 個唯一值。對於每種方法,我進行了四次測試(每次嘗試多次,平均結果):一次 20 列,一次 5 列,1 列有很多值(3.2M)和 1 列有少量值( 167)。以下是結果,按從快到慢的順序排列
測試結果(以秒為單位):
Method 20_Columns 5_Columns 1_Column (Large) 1_Column (Small) 1) Count/GroupBy 10.8 4.8 2.8 0.14 2) CountDistinct 12.4 4.8 3 0.7 3) dense_rank 226 30 6 4.33 4) Count+Max 98.5 44 16 12.5筆記:
- 有趣的是,最快的兩種方法(到目前為止,兩者之間只有很小的差異)都是為每一列送出單獨查詢的方法(在結果 #2 的情況下,查詢包括一個子查詢,所以有實際上是每列送出兩個查詢)。可能是因為與記憶體需求方面的性能損失相比,通過限製表掃描次數獲得的收益很小(只是猜測)。
- 雖然 dense_rank 方法絕對是最優雅的,但它似乎並不能很好地擴展(見 20 列的結果,這是迄今為止四種方法中最差的),即使在小規模上也無法與的表現
Count。感謝您的幫助和建議!
SELECT COUNT(*) FROM (SELECT ColumnName FROM TableName GROUP BY ColumnName) AS s;
GROUP BY選擇不同的值,包括 NULL。COUNT(*)將包括 NULL,而不是COUNT(ColumnName)忽略 NULL。
OP自己的解決方案的發展:
SELECT COUNT(DISTINCT acolumn) + MAX(CASE WHEN acolumn IS NULL THEN 1 ELSE 0 END) FROM atable