Sql server 2005 服务器将尝试选择最合适的(最有选择性的)

Sql server 2005 服务器将尝试选择最合适的(最有选择性的),sql-server-2005,stored-procedures,indexing,large-data-volumes,Sql Server 2005,Stored Procedures,Indexing,Large Data Volumes,还要注意,在生产表上放置NOLOCK提示是一个非常糟糕的主意。您可以在单个查询中进行脏读取 如果id\u ent是所有表中PRIMARY KEY的一部分,最好将其替换为常量。此查询: SELECT * FROM Transactions t JOIN TransactionTypesCurrencies ttc ON ttc.trnTypeCurrencyID = t.trnTypeCurrencyID WHERE t.id_ent = @id_ent

还要注意,在生产表上放置
NOLOCK
提示是一个非常糟糕的主意。您可以在单个查询中进行脏读取

如果
id\u ent
是所有表中
PRIMARY KEY
的一部分,最好将其替换为常量。此查询:

SELECT  *
FROM    Transactions t
JOIN    TransactionTypesCurrencies ttc
ON      ttc.trnTypeCurrencyID = t.trnTypeCurrencyID 
WHERE   t.id_ent = @id_ent
        AND ttc.id_ent = @id_ent
通常比这个好:

SELECT  *
FROM    Transactions t
JOIN    TransactionTypesCurrencies ttc
ON      ttc.id_ent = t.id_ent
        AND ttc.trnTypeCurrencyID = t.trnTypeCurrencyID 
WHERE   t.id_ent = @id_ent
,因为可以进行早期筛选

如果您只有一个
id\u ent
值,那么这没有什么区别,但是如果您添加另一个值,它将为自己付费

更新:

如果您有多个条件下筛选的循环查询,并且速度较慢,您可以考虑在几个条件下创建附加复合索引。

有关如何做到这一点的建议,请参阅我博客中的这篇文章:


您只需在
WHERE
子句中使用的所有字段上创建单独的索引,即
transactionDate
transactionStatusID
等。如果您有一个
id
作为附加筛选器,请将其作为前导列包括在内:

CREATE INDEX ix_transaction_transactionDate ON transaction (id_ent, transactionDate)
CREATE INDEX ix_transaction_transactionStatusID ON transaction (id_ent, transactionStatusID)
-- etc.
请注意,对于每个查询,只使用一个索引,
SQL Server
将尝试选择最合适的索引(最有选择性的索引)

还要注意,在生产表上放置
NOLOCK
提示是一个非常糟糕的主意。您可以在单个查询中进行脏读取

如果
id\u ent
是所有表中
PRIMARY KEY
的一部分,最好将其替换为常量。此查询:

SELECT  *
FROM    Transactions t
JOIN    TransactionTypesCurrencies ttc
ON      ttc.trnTypeCurrencyID = t.trnTypeCurrencyID 
WHERE   t.id_ent = @id_ent
        AND ttc.id_ent = @id_ent
通常比这个好:

SELECT  *
FROM    Transactions t
JOIN    TransactionTypesCurrencies ttc
ON      ttc.id_ent = t.id_ent
        AND ttc.trnTypeCurrencyID = t.trnTypeCurrencyID 
WHERE   t.id_ent = @id_ent
,因为可以进行早期筛选

如果您只有一个
id\u ent
值,那么这没有什么区别,但是如果您添加另一个值,它将为自己付费

更新:

如果您有多个条件下筛选的循环查询,并且速度较慢,您可以考虑在几个条件下创建附加复合索引。

有关如何做到这一点的建议,请参阅我博客中的这篇文章:


您可以通过使用探查器来记录工作负载,然后使用索引调整向导来确定最能处理工作负载的索引,从而获得一些经验信息


创建的索引越多,插入所需的工作就越多,因此,在搜索的所有内容上创建索引可能不是一个好主意。

您可以通过使用探查器记录工作负载,然后使用索引调整向导来确定最能处理工作负载的索引,从而获得一些经验信息


创建的索引越多,插入所需的工作就越多,因此在搜索的所有内容上创建索引可能不是一个好主意。

我发现在这种情况下,创建临时表比创建普通表表达式更快。这还允许您返回分页的总数。

我发现在这种情况下,创建临时表比创建公共表表达式更快。这还允许您返回分页的总数。

在创建索引之前,我会问自己一些问题:

  • 此表是只读还是读写
  • ReadWrite—每次对表进行更新/删除时,索引都会被更新。对于“选择”来说,它可能很快,但是对于插入、更新和删除来说,它可能很慢。如果表上有大量索引,则会增加优化器为查询计划选择次优索引的机会

  • 您正在动态创建查询。我要做的是尝试在QA(或特定时间的生产数据库)上运行跟踪,并查看用户正在尝试运行什么。您可以将数据库从生产环境转储到您的沙盒/尝试工具,如索引优化向导(它可以告诉您需要什么索引),等等,以找到瓶颈所在。问题不必仅限于此SP,还可能存在死锁、临时表/临时数据库使用不当等

  • 如果您有理由相信这个表是罪魁祸首,那么您还应该尝试水平分区这个表

  • 执行任何查询时,请查看执行计划并查找表扫描,这通常意味着缺少某些索引

  • ,及


  • 在创建索引之前我问自己的问题:

  • 此表是只读还是读写
  • ReadWrite—每次对表进行更新/删除时,索引都会被更新。对于“选择”来说,它可能很快,但是对于插入、更新和删除来说,它可能很慢。如果表上有大量索引,则会增加优化器为查询计划选择次优索引的机会

  • 您正在动态创建查询。我要做的是尝试在QA(或特定时间的生产数据库)上运行跟踪,并查看用户正在尝试运行什么。您可以将数据库从生产环境转储到您的沙盒/尝试工具,如索引优化向导(它可以告诉您需要什么索引),等等,以找到瓶颈所在。问题不必仅限于此SP,还可能存在死锁、临时表/临时数据库使用不当等

  • 如果您有理由相信这个表是罪魁祸首,那么您还应该尝试水平分区这个表

  • 执行任何查询时,请查看执行计划并查找表扫描,这通常意味着缺少某些索引

  • ,及


  • 提前谢谢。问题是,我可以搜索任何字段组合,可以是日期和交易类型,也可以是交易类型和用户ID等。。。另一件事是创建这个表的人将字段Id作为主键的一部分(Id+transactionID)