我想对报告执行此操作,但我的表中有 20,000,000 条记录,这会导致我的应用程序超时。
SELECT
T.transactionStatusID,
TS.shortName AS TransactionStatusDefShortName,
count(*) AS qtyTransactions
FROM
Transactions T
INNER JOIN TransactionTypesCurrencies TTC
ON T.id_Ent = TTC.id_Ent
AND T.trnTypeCurrencyID = TTC.trnTypeCurrencyID
INNER JOIN TransactionStatusDef TS
ON T.id_Ent = TS.ent_Ent
AND T.transactionStatusID = TS.ID
WHERE
T.id_Ent = @id_Ent
GROUP BY
T.transactionStatusID,
TS.shortName
据我所知,COUNT(*) 会导致全表扫描,这会使我的查询花费太多时间,我正在使用 MS SQL 2005,有什么帮助吗?
编辑:
项目负责人告诉我,查询只是为了一天,它可以提供帮助吗?
最佳答案
as far as i know COUNT(*) causes a full table scan and it makes my query to take too much time, im Using MS SQL 2005, any help ?
COUNT(*)
可以使用任何能够给出答案的来源,其中包括索引。
就您而言,我将使用 trnTypeCurrencyID
在 (id_ent, transactionStatusID)
上创建覆盖索引:
CREATE INDEX ON Transactions (id_ent, transactionStatusID) INCLUDE (trnTypeCurrencyID)
并稍微重写查询:
SELECT transactionStatusID, qtyTransactions, TS.shortName
FROM (
SELECT T.transactionStatusID,
COUNT(*) AS qtyTransactions
FROM Transactions T
JOIN TransactionTypesCurrencies TTC
ON TTC.id_Ent = T.id_Ent
AND TTC.trnTypeCurrencyID = T.trnTypeCurrencyID
WHERE T.id_Ent = @id_Ent
GROUP BY
T.transactionStatusID
) TD
JOIN TransactionStatusDef TS
ON TS.ent_Ent = @id_Ent
AND TS.ID = TD.transactionStatusID
索引将根据 id_ent
进行过滤,并根据 transactionStatusID
进行并行化。由于您已经覆盖了 trnTypeCurrencyID,引擎将不必查找表中的值,它已经存在于索引中。
GROUP BY
子句还仅包含索引中的列,因此它的并行性更好。
更新:
通过添加 WITH (ONLINE = ON)
,您可以在创建索引期间使表保持可操作状态:
CREATE INDEX ON Transactions (id_ent, transactionStatusID) INCLUDE (trnTypeCurrencyID) WITH (ONLINE = ON)
关于sql-server-2005 - 对大量数据选择 Count(*),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1874888/