【IT168技术文档】
过滤操作对绝大多数复杂查询的编写来说非常重要。虽然在某些情况下你不需要用到过滤器,例如编写一个用来检索我国所有省份列表的简单查询就不需要; 不过在大多数情况下,你需要过滤数据以便通过更精确的设定缩小查询范围。例如,当你需要一份以字母G开头的所有省份名单时,就得用到过滤机制。
开发人员和数据库管理员有可以用各种运算符来执行这样的过滤操作。在决定使用何种运算符时需要优先考虑的问题是查询性能。可能有那么一些专家声称某些特定运算符要比别的好用,并提供一些经验法则之类的东西来指导您的选择。虽然这些经验法则大体而言还是不错的,不过对于任何的个别案例来说,都存在很多影响查询性能的因素,事实证明这些因素比一般法则更重要。对个别查询的用法和执行计划不加研究,而严格地按照经验规则来选择运算符,可能会导致查询达不到非常好的性能。
选择非常好的运算符
当我们将要为查询决定非常好的运算符的选择时,首先要考虑将来该查询的使用情况。如果这个查询的使用频率很低,而且属于某个在活动不频繁时间才运行的进程的一部分(如深夜运行的SQL Server集成服务或数据转换服务包),那么长时间查询可能会比较合适。另一方面,如果可以运行该查询的时间很短,例如主营网上购物的商店,就需要对每项交易都执行一个查询,那么您可能会希望把时间花在获得非常好的查询性能上,也就是说不仅要保证客户的体验,也要维护数据库服务器的稳定。
我们还需要考虑如何为过滤取值,这些值又是从何处获得的。过滤值是单个值还是多个值?某些运算符能容纳的过滤值比其他运算符多。从另外一个表或子查询获得多个过滤值,而不是传递特定值,也可能会影响到你对运算符的选择。
此外,当我们将要选择运算符时,还有一个重要因素需要考虑,那就是索引。如果某个适当的索引可用时,SQL Query Optimizer通常会用该索引去执行索引查找操作。如果没有可用索引,或索引不是最适合的,那数据库必须先执行表扫描或索引扫描,这样尤其会导致性能下降。不过,如果被查询的表包含的行比较少,那表扫描或索引扫描执行起来确实会比索引查找要快。当评价执行计划时,我们必须要考虑这些条件。
评价执行计划
类似于“EXISTS逻辑运算符比IN逻辑运算符更好用”这类大而化之的评价常常会左右我们的思维。在决定选择哪个运算符的时候,我们不能单纯地把某人的教条当圣经来用。更好的做法是评价执行计划,以便为数据库测试我们在其中编写的查询。执行计划为我们揭示是否了执行表扫描或索引扫描,并阐明该查询各步骤的相对性能情况。
我们可以使用Enterprise Manager 中的Query Analyzer工具(SQL Server 2000)或者通过SQL Server Management Studio(SQL Server 2005)来查看执行计划。
测试样本查询
为了更好地阐明测试过程,本文将以AdventureWorks样本数据库为例,通过不同的变化设置来测试一个用来检索三个特定产品销售细节的查询。我们需要准备以下的测试环境:SQL Server 2005标准版、SQL Server Management Studio、SQL Server Profiler和AdventureWorks样本数据库。假设查询的结果会在一个网页应用程序的GridView对象中显示。当页面应用程序处于回传状态时,该GridView对象就会开始组建;因此,必须快速执行查询,而且执行的频率也要很高(假设这是一个访问率很高的网站)。
等于比较运算符和IN逻辑运算符
正如上面提到的,我们需要用一个查询来检索三个特定产品销售情况的详细资料。我们可以使用带等于比较运算符过滤的WHERE从句或带IN逻辑运算符过滤的WHERE从句来完成这个任务。
比较运算符只能用来比较两个值。为了检测三个特定ProductID之间的等价关系,我们还需要用到OR运算符。下面就是使用了等于比较运算符的查询语句:
SELECT SalesOrderID, CarrierTrackingNumber, ProductID, UnitPrice FROM AdventureWorks.Sales.SalesOrderDetail WHERE (ProductID = '762') or (ProductID = '754') or (ProductID = '770')