Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在(子查询)或(列表)性能问题中_Sql_Sql Server - Fatal编程技术网

Sql 在(子查询)或(列表)性能问题中

Sql 在(子查询)或(列表)性能问题中,sql,sql-server,Sql,Sql Server,我想根据原始表中的字段是否在两个列表中列出一个列表。因此,我的代码是: SELECT * FROM ListofPlaces WHERE Property = 'MODERATE' and (HOMELAND in ( SELECT distinct HOMELAND FROM PLANS WHERE left(plans.code, 1) = '1') or HOMELAND in ( 'PlaceA'

我想根据原始表中的字段是否在两个列表中列出一个列表。因此,我的代码是:

SELECT *
FROM ListofPlaces
WHERE Property = 'MODERATE'
    and (HOMELAND in (
        SELECT distinct HOMELAND
        FROM PLANS
        WHERE left(plans.code, 1) = '1') 
    or HOMELAND in (
        'PlaceA'
        , 'PlaceB'
        , 'PlaceC'
        , 'PlaceD'
        , 'PlaceE'))
列表和子查询将分别正常工作,子查询为00:00:01.43,列表为00:00:00.13,但是一旦组合起来,它们大约需要一分钟

我尝试过使用左连接,但这会导致性能更显著的降低

“平面图”是一个更大的表格,共有4M+行,而位置列表少于1000个


我的问题是,我是否在有效地使用and/or运算符,如果是,是否有更有效的方法来运行此查询?

请尝试使用
联合重写此查询:

SELECT *
FROM ListofPlaces
WHERE Property = 'MODERATE' AND
      HOMELAND IN (SELECT HOMELAND
                   FROM PLANS
                   WHERE left(plans.code, 1) = '1'
                  ) 
UNION
SELECT *
FROM ListofPlaces
WHERE Property = 'MODERATE' AND
      HOMELAND in ('PlaceA', 'PlaceB', 'PlaceC', 'PlaceD', 'PlaceE');

优化器有时会被
s所混淆<如果两个列表包含相似的元素,则此处可能需要代码>联合
,而不是
联合所有
。否则,如果您知道它们是不相交的,请使用
UNION ALL

尝试使用
UNION
重写此代码:

SELECT *
FROM ListofPlaces
WHERE Property = 'MODERATE' AND
      HOMELAND IN (SELECT HOMELAND
                   FROM PLANS
                   WHERE left(plans.code, 1) = '1'
                  ) 
UNION
SELECT *
FROM ListofPlaces
WHERE Property = 'MODERATE' AND
      HOMELAND in ('PlaceA', 'PlaceB', 'PlaceC', 'PlaceD', 'PlaceE');
优化器有时会被
s所混淆<如果两个列表包含相似的元素,则此处可能需要代码>联合
,而不是
联合所有
。否则,如果您知道它们是不相交的,请使用
UNION ALL

为什么不合并

SELECT LoP.*
FROM ListofPlaces LoP
left join PLANS Pl
  on LoP.HOMELAND = Pl.HOMELAND
WHERE Property = 'MODERATE'
    and (left(plans.code, 1) = '1' 
    or LoP.HOMELAND in (
        'PlaceA'
        , 'PlaceB'
        , 'PlaceC'
        , 'PlaceD'
        , 'PlaceE'))
为什么不加入

SELECT LoP.*
FROM ListofPlaces LoP
left join PLANS Pl
  on LoP.HOMELAND = Pl.HOMELAND
WHERE Property = 'MODERATE'
    and (left(plans.code, 1) = '1' 
    or LoP.HOMELAND in (
        'PlaceA'
        , 'PlaceB'
        , 'PlaceC'
        , 'PlaceD'
        , 'PlaceE'))

如果
code
上存在索引,请尝试
plans.code,如“1%”
而不是
left(plans.code,1)=“1”
不知道这是否会对性能产生影响,但
distinct
可以忽略。我同意@Serg的观点,即
如“1%”
很可能击败
左(…
,甚至可能没有计划索引。code。如果
代码上存在索引,请尝试
计划。代码如“1%”
而不是
左(计划。代码,1)='1'
不知道这是否会对性能产生影响,但是可以忽略
distinct
。我同意@Serg的观点,即
如'1%
可能会超过
left(…
,甚至可能没有关于plans.code的索引。这也是我的第二个想法john,不幸的是性能也很差-感谢您的帮助虽然这是我的第二个想法john,不幸的是性能也很差-谢谢您的帮助