我有一个程序从Visual FoxPro表中提取数据并使用VB.net转储到数据集中。我的连接字符串工作得很好,我使用的查询通常以相当快的速度运行。然而,当我更多地运行它时,我已经了解到存在大量的“坏”和#34;我桌子上的数据。所以现在,我正在尝试优化我的查询以缓冲"坏"数据,但我认为这是一个非常小的调整已经产生了巨大的性能损失,我不是特别确定原因。
我的原始查询是:
'Pull desired columns for orders that have not "shipped" and were received in past 60 days.
'To "ship", an order must qualify with both an updated ship date and Sales Order #.
sqlSelect = "SELECT job_id,cust_id,total_sale,received,due,end_qty,job_descr,shipped,so "
sqlFrom = "FROM job "
sqlWhere = "WHERE fac = 'North Side' AND shipped < {12/30/1899} AND so = '' AND received >= DATE()-60;"
sql = sqlSelect & sqlFrom & sqlWhere
这个运行时间约为20秒;虽然我更喜欢它更快,但这不是问题。在我原来的测试(以及偶尔的调试)中,我将sqlWhere
替换为sqlWhere = "WHERE job_id = 127350"
。这几乎是瞬间完成的。
现在出现问题:我用
替换了sqlWhere
'Find jobs that haven't "shipped" OR were received within last 21 days.
'Recently shipped items are desired in results.
sqlWhere = "WHERE fac = 'North Side' AND ((shipped < {12/30/1899} AND so = '') OR received >= DATE()-21);"
我的表现跃升至约3分40秒。此时间与使用sqlWhere = "WHERE received >= DATE();"
的时间几乎完全相同。
我不是这些表的主持人;我只是从他们那里为我们的用户创建一系列报告。我最好的猜测是收到的字段没有编入索引,这是我性能下降的原因。但是,当我的第一次搜索返回大约100条记录时,仅从今天开始提取作业大约返回5,并且仍然需要大约11倍。
所以我的问题是三部分: 1)有人能够解释我现在遇到的现象吗?我觉得我有点走上正轨,但我对SQL的了解仅限于在其他语言中进行间接使用...... 2)我有什么遗漏,或者有更好的方法来获得我需要的结果吗?有大量的记录没有发货&#34;,只是因为用户只输入发货日期或s / o,而没有做另一个。我需要一种方法来查看最近的订单(无论&#34;已发货&#34;状态),然后还查看较少的近期订单,其中包含&#34;坏&#34;数据,所以我可以让用户习惯清理数据。 3)过度约束WHERE子句是不好的SQL实践?如果我运行十五个字段比较,与嵌套的AND / OR一起加入,我是否会浪费时间做一些更清洁的事情?
非常感谢, 乙
答案 0 :(得分:0)
如果要在WHERE字符串中查找非索引记录,则SQL引擎必须执行表扫描,即 - 查看表中的每条记录。
两个查询之间的区别是OR而不是AND。当AND中包含非索引列时,SQL引擎可以使用索引来缩小它必须为非索引列查看的记录数。当你有一个OR时,它现在必须查看表中的每个记录并在该列上进行比较。
在Received列上添加索引可能会解决性能问题。
通常,您希望在WHERE子句中发生两件事。 1.非索引列的主要条件 2.在列上使用计算。例如,做WHERE Shipped-2&lt; date()通常比Shipped&lt; Date()+ 2,因为前者通常不允许使用索引。
通过多个WHERE子句优化查询通常是件好事。返回应用程序所需的记录越少,性能就越好,但您需要有适当的索引。