2011-12-01 129 views
2

MAIN_TABLE中有超过1亿条记录; SECURITY_TABLE中有超过2.5亿条记录。我试图从MAIN_TABLE中检索符合过滤条件的对象,并且当前用户也可以访问(访问记录存储在security_table中)。我使用类似以下内容进行查询:短语SQL语句

01 select col1, col2, col3 from main_table 
02 where (col4 like '%something%' 
03 or col4 like '%something else%' 
04 or col4 like "%some other thing%') 
05 AND 
06 col1 in (select st_col1 from security_table 
07 where st_id in (
08  select col1 from main_table 
09  where (col4 like '%something%' 
10  or col4 like '%something else%' 
11  or col4 like "%some other thing%' 
12  ) 
13 ) 
14 AND 
15 st_user_id = current_user_id 
16) 

如果我必须在线路过滤标准2-4(标准A)五场比赛,将过滤条件在9-11行(标准B)重新扫描MAIN_TABLE中的全部1亿条记录,或仅包含2-4行返回的5条记录?

回答

2

它取决于很多东西的™,包括您的RDBMS(SQL Server,Oracle,MySQL等)。

但是,其中大多数的答案是maybe?

例如,SQL Server可能会检查第二个条件,如果查询分析器根据索引和基数确定它会更快。他们也可能很可能被并行检查,并且在哈希表中比较两个检查的内容以找到交集。

对于您的特定情况,查询的性质需要进行表扫描,因此无关紧要。

+0

+1 RDBMS将决定如何应用您的子句。 – Matthew

0

您的条件:

OR LIKE '% ... %' 

将需要扫描,并且每增加一个类似OR标准的额外扫描。

在第05行后追加AND子句时,可以从前一个条件返回的集合中完成。 但是您无法控制SQL Server首先会使用哪种标准。它会尝试自行优化。

检查您的查询计划是否真的在做什么。

0

这将重新扫描整个表 - 内子查询与主查询完全独立的,即使它是做同样的事情(因此似乎是完全多余的 - 如果你在内部有不同标准子查询,它不会是多余的)。

+0

我添加内部子查询的唯一原因是,如果用户可以访问大量对象(例如,安全表中的行数),我会将比较减少到只有那些符合过滤标准。如果这些表格在1000年的记录中,我不会在意,但是数百万?这是一个完整的'无球赛'。 –