【问题标题】:Need filtered result optimised query需要过滤结果优化查询
【发布时间】:2015-09-17 03:32:42
【问题描述】:

我有一张桌子叫Device:

        Device Table
id    deviceName     genId       description               overview 
1      PV motor       5       motor capacity  5        motor load is good
2      puf pannel     6       puf capacity  2          puf is for small load
3      gd motor       5       motor capacity 7         motor load is very good
4      rg motor       5       capacity is 3            low capacity

现在假设该表有数千条记录,我需要添加对行的搜索,例如 genId=5 and description Like = '%motor%' OR Overview Like='%motor%'
搜索结果将是

1      PV motor       5       motor capacity  5        motor load is good
3      gd motor       5       motor capacity 7         motor load is very good

我需要构建查询,首先从表中搜索 genId 5,然后然后搜索具有类似电机文本的描述和概述。因为如果我的表有 100 条记录并且其中只有 5 条的 genId 设置为 5,那么我的文本搜索查询将在这 5 行而不是 100 行上执行。

我的搜索查询:

Select * 
From Device 
where (genId=5) And (description Like '%motor%' Or overview Like '%motor%') 

谁能帮我创建优化查询?

【问题讨论】:

  • 为什么您认为使用单独的临时表分两步进行搜索会更快?
  • @CL。 :like是一个繁重的操作,这里平均可以搜索300-1000字。因此,如果我首先从 1000 行过滤到 20 行(按 genId),那么 Like 查询将仅在 20 行而不是全部 1000 行中执行,如果我错了,请纠正我。

标签: sql sqlite query-optimization


【解决方案1】:

您的查询已经尽可能优化。

LIKE 本身并不慢;它缓慢的是从磁盘加载所有表行,而 LIKE 通常需要这样做,因为它无法使用索引优化其查找。

但是,当genId 列上没有索引时,无论如何都需要加载所有行来检查这些值,因此插入一个额外的步骤将是不必要的:

> EXPLAIN QUERY PLAN Select * From Device where (genId=5) And (description Like '%motor%' Or overview Like '%motor%');
0|0|0|SCAN TABLE Device

另一方面,如果在genId 列上有索引,那么您不需要进行任何手动优化,因为数据库会自动查找匹配的@ 987654324@ 索引中的行,然后只检查那些上的 LIKE 数学:

> CREATE INDEX genId_index ON Device(genId);
> EXPLAIN QUERY PLAN Select * From Device where (genId=5) And (description Like '%motor%' Or overview Like '%motor%');
0|0|0|SEARCH TABLE Device USING INDEX genId_index (genId=?)

【讨论】:

    【解决方案2】:

    在这种情况下,您可以进行子查询

    Select * 
    From (Select * From Device where (genId=5)) 
    where description Like '%motor%' Or overview Like '%motor%'
    

    这里,首先会先执行子查询,然后再应用 where 条件。这是我所知道的

    【讨论】:

    【解决方案3】:

    那为什么要分开搜索呢?只需将 AND 更改为 OR,您的查询将获取所有可能的场景。

    SELECT * FROM 
       Device 
    WHERE 
        genId = 5 
    OR 
        description Like '%motor%' 
    OR 
        overview Like '%motor%'; 
    

    【讨论】:

    • 我认为这不会降低成本,目前查询我的数据库没有太多记录,但将来可能会有。
    • 但是您在问题中解释的标准无论如何都需要搜索这三个字段。正确的?还是我缺少什么?
    • 标准基于 3 个字段,您没看错。 Like 命令是一项繁重的操作。所以我一直在寻找一些优化的解决方案。无论如何,我现在使用的是相同的查询。
    • 太好了,请不要忘记接受正确的答案;)
    • 附言。除非您可以更改标准,否则“LIKE”的成本很高,这是完全正确的,恐怕您还可以这样做
    【解决方案4】:

    我认为最好不要使用OR 运算符并减少使用Like 运算符,如下所示:

    SELECT *
    FROM Device
    WHERE (genId = 5)
      AND (1 = CASE WHEN description Like '%motor%' THEN 1
                    WHEN overview Like '%motor%' THEN 1
                    ELSE 0
               END)
    

    或者这个

    SELECT *
    FROM Device
    WHERE (genId = 5)
      AND (description || ':' || overview Like '%motor%')
    

    【讨论】:

    • 我喜欢description || ':' || overview Like '%motor%' 语法,谢谢分享,但你确定它与其他语法相比降低了查询的成本吗?我认为这两种语法最终都会在这两个字段中搜索相似的值
    猜你喜欢
    • 1970-01-01
    • 2014-02-15
    • 1970-01-01
    • 2014-01-12
    • 2012-08-12
    • 2016-02-02
    • 2014-03-05
    • 1970-01-01
    相关资源
    最近更新 更多