我的SQL语句有问题,详见下文。查询返回我需要的结果,但需要花费大量的时间来执行。我现在在db中有这么多记录,通常不会加载页面。
SELECT dscan.guid, dscan.drive, dscan.folder, dscan.filename, source.guid
FROM source
RIGHT JOIN dscan ON (
(source.guid & '_dtr' = dscan.guid OR source.guid & '_dto' = dscan.guid OR source.guid = dscan.guid)
AND dscan.guid LIKE '%" & Replace(strSearch_guid, "'", "''") & "%'
AND dscan.filename NOT LIKE '.[_]%'
AND dscan.drive = 'Z:')
WHERE source.guid Is Null
ORDER BY dscan.drive, dscan.guid
从我在网上找到的,JOIN语句中的OR是一个问题,但我无法弄清楚如何解决这个问题。
我正在将数据库记录与文件名进行比较以识别错误 - 但文件名有时会包含“_dtr”或“_dto”附件,我必须将其考虑在内。
答案 0 :(得分:1)
使用构造的谓词比较值,以及在开头使用wildcrads的“Like”将需要完整的表扫描。在您重新设计架构以消除此问题之前,这将是大型表的主要性能影响。但是,您可以通过合并三个单独的sql语句来消除OR中的性能损失。试试这个:
SELECT D.guid, D.drive, D.folder, D.filename, S.guid
FROM dscan D Left Join source S
ON S.guid & '_dtr' = D.guid
AND D.guid LIKE '%" & Replace(strSearch_guid, "'", "''") & "%'
AND D.filename NOT LIKE '.[_]%'
AND D.drive = 'Z:')
WHERE S.guid Is Null
Union
SELECT D.guid, D.drive, D.folder, D.filename, S.guid
FROM dscan D Left Join source S
ON S.guid & '_dto' = D.guid
AND D.guid LIKE '%" & Replace(strSearch_guid, "'", "''") & "%'
AND D.filename NOT LIKE '.[_]%'
AND D.drive = 'Z:')
WHERE S.guid Is Null
Union
SELECT D.guid, D.drive, D.folder, D.filename, S.guid
FROM dscan D Left Join source S
ON S.guid = D.guid
AND D.guid LIKE '%" & Replace(strSearch_guid, "'", "''") & "%'
AND D.filename NOT LIKE '.[_]%'
AND D.drive = 'Z:')
WHERE S.guid Is Null
ORDER BY D.drive, D.guid
答案 1 :(得分:0)
我认为你应该尝试用一些括号来解剖它。
((source.guid&'_dtr'= dscan.guid)OR(source.guid&'_dto'= dscan.guid)OR(source.guid = dscan.guid))
答案 2 :(得分:0)
or
是臭名昭着的表演吸盘。请尝试使用in
子句。:
SELECT dscan.guid, dscan.drive, dscan.folder, dscan.filename, source.guid
FROM source
RIGHT JOIN dscan ON (
dscan.guid in (source.guid & '_dtr', source.guid & '_dto', source.guid)
AND dscan.guid LIKE '%" & Replace(strSearch_guid, "'", "''") & "%'
AND dscan.filename NOT LIKE '.[_]%'
AND dscan.drive = 'Z:')
WHERE source.guid Is Null
ORDER BY dscan.drive, dscan.guid
但是,最好的是,使用您的查询执行计划来真正了解数据库引擎正在做什么。然后,您可以看到真正的瓶颈所在,以及可以添加哪些索引以加快查询速度。
答案 3 :(得分:0)
也许你可以重新订购东西。你可以尝试:
答案 4 :(得分:0)
实际上,我认为您的性能问题不是来自“OR”,而主要是因为您使用串联字符串来进行连接。
同时加入字符串数据并不能提供最佳性能。另一方面,如果列被索引(在它们上添加索引),它会有所帮助(如果你没有再次连接字符串)
作为一个解决方案,我不知道是否有可能或想要在该表中添加列并包含已添加“extensions”的字符串版本,因此查询不需要连接它们?
这些是一些解决方法,而不是真正的解决方案
答案 5 :(得分:0)
我重写了你的查询:
SELECT d.guid,
d.drive,
d.folder,
d.filename,
src.guid
FROM DSCAN d
JOIN (SELECT s.quid,
s.quid & '_dtr' AS DTR,
s.quid & '_dto' AS DTO,
FROM SOURCE s
WHERE s.guid IS NOT NULL) src ON d.guid IN (s.quid, s.dtr, s.dto)
WHERE d.guid LIKE '%' & REPLACE(strSearch_guid, "'", "''") & '%'
AND d.filename NOT LIKE '.[_]%'
AND d.drive = 'Z:'
ORDER BY d.drive, d.guid
我假设您在OP中有一个关于source.guid IS NULL的类型 - 没有意义,您只需要NULL source.guid记录,然后连接到它们。
此:
RIGHT JOIN dscan ON (source.guid & '_dtr' = dscan.guid OR
source.guid & '_dto' = dscan.guid OR
source.guid = dscan.guid)
...只会在guid列上使用索引(假设存在一个)来创建值 not 进行比较。如果您需要这样做,最好在内联视图或CTE /子查询保理中构建它们。
答案 6 :(得分:0)
现在让我们通过以下内容查看您的select语句:
SELECT dscan.guid,dscan.drive,dscan.folder,dscan.filename,source.guid
来源
RIGHT JOIN dscan ON
并以此结束:
WHERE source.guid是否为空 ORDER BY dscan.drive,dscan.guid
因此,如果我正确读取您尝试读取dscan表中的所有内容以及与源表匹配的anthing。
??如果您查找source.guid为null,究竟如何链接这两个表?因为如果source.guid为null,为什么你会这样做:
<强>源
RIGHT JOIN dscan ON(
(source.guid&amp;'_dtr'= dscan.guid OR source.guid&amp;'_dto'= dscan.guid OR source.guid = dscan.guid)
AND dscan.guid LIKE'%'&amp; Replace(strSearch_guid,“'”,“''”)&amp;“%'
AND dscan.filename NOT LIKE'。[_]%'
AND dscan.drive ='Z:')
您的查询需要很长时间,因为它会在联接中丢失。你的尝试 让它过滤太多东西并过滤像'%blah blah%'那样 帮助加快速度。检查源表和dscan表上是否有正确的索引。
为什么 WHERE source.guid是NUll 您需要source.guid与dscan表中的dscan.guide匹配。