【问题标题】:SQL query performance LIKE and wildecards vs. INSQL 查询性能 LIKE 和通配符与 IN
【发布时间】:2012-02-22 16:05:27
【问题描述】:

如果这两个查询会有很大的性能差异,我只是担心

SELECT 
  `items_id`, `sport_id`, `sport`, `title`, `url`, 
  `Select3`, `Select6`, `id`, `data`,`image` as image,
  concat('index.php?option=sports&item=',`items_id`,'&p=C108-M108') as count_url
FROM 
  qy9zh_dataitems
WHERE Select6 LIKE '%sport%'
ORDER BY `Select9` DESC LIMIT 0, 4


SELECT 
  `items_id`, `sport_id`, `sport`, `title`, `url`, 
  `Select3`, `Select6`, `id`, `data`,`image` as image,
  concat('index.php?option=sports&item=',`items_id`,'&p=C108-M108') as count_url
FROM 
  qy9zh_dataitems 
WHERE Select6 in ('sport') 
ORDER BY `Select9` DESC LIMIT 0, 4

查询工作得很好..他们俩..只是担心性能:)

编辑:当我做一些测试时,一件奇怪的事情是这样的:

SELECT * FROM qy9zh_dataitems WHERE Select6 in ('kvinna') LIMIT 0, 40000

总共 29,051 个,查询耗时 0.2581 秒

SELECT * FROM qy9zh_dataitems WHERE Select6 LIKE ('%kvinna%') LIMIT 0, 40000

总共 29,113 个,查询耗时 0.2218 秒

【问题讨论】:

  • 你知道这两个查询有不同的结果吗?
  • 结果不是问题..只是好奇性能:)
  • kill 性能问题是第一个查询中的起始通配符。
  • 您在编辑中得到的结果可能是因为您紧接着运行它们;缓存会影响结果。只需执行 EXPLAIN PLAN 并查看输出 - LIKE 查询将显示需要 TABLE SCAN,这意味着由于起始通配符必须检查每一行。
  • 这两个查询不是一个意思,你应该比较Select6 in ('kvinna')Select6 = 'kvinna'。两者都查找Select6 等于'kvinna' 的行。但是Select6 LIKE ('%kvinna%') 会查找Select6 包含'kvinna' 的行。它还会找到'abc kvinna xyz'

标签: mysql sql performance select sql-like


【解决方案1】:

如果在列上定义了索引,并且您正在寻找该列的开头,如

name LIKE 'Jo%' 

索引可以用来加速查询。但是,如果您正在寻找单词的任何部分,如

name LIKE '%man%' 

索引无法使用。

IN子句一般来说很快,但是我不知道它是否可以利用索引。

查询的速度取决于适当索引的可用性、表的大小、值的分布(许多行具有相同的值,每行具有不同的值),当然还取决于查询本身。我认为您的问题无法得到普遍回答。进行测试和比较!

【讨论】:

    【解决方案2】:

    这些甚至不是相同的查询,因此无法比较性能。

    第二个查询可以使用Select6 上的索引将行限制为等于sport 的行,而第一个查询必须查看每一行以查看它是否在@ 内容中的任何位置包含sport 987654324@。您正在尝试比较苹果和橙子。

    【讨论】:

    • 对不起..我不是后端/数据库人..只是一个简单的前端开发人员;)有什么方法可以在第一个查询中使用索引吗?我的问题是第二个确实让我使用通配符:/
    • 不,当您使用LIKE 开头的通配符时,您不能使用索引。想想纯文本的含义:Give me all the rows where Select6 starts with 0 or more characters, then contains the word 'sport', and then has anything (or nothing) after it. 因为匹配可能是sportabracadabara sports are like magic,所以索引无法帮助搜索。如果您可以将其限制为开头的特定单词 (LIKE 'sport%'),则索引可以有所帮助(尽管没有类似的索引仍然可以稍微快一些,因为服务器可以限制行。)
    【解决方案3】:

    这些是非常不同的标准。

    WHERE Select6 LIKE '%sport%'
    

    将查找 select6 包含单词运动的情况。

    WHERE Select6 in ('sport') 
    

    将查找 select6 是单词 sport 的情况。

    一个 IN 条件允许您指定一个可能值的列表,并且应该非常快,如果您已为该字段编制索引。点赞,尤其是在字符串中的任何位置查找单词的点赞可能根本难以索引。 Where select6 like 'sport%' 会寻找 select6 以单词 sport 开头并且可以索引的情况。

    【讨论】:

      【解决方案4】:

      正如其他人所发布的,基本索引不能用于带有前导通配符的搜索。如果您认为这些查询将是最常见的,您可以查看 MySQL 中的全文搜索功能。

      全文搜索提供了一种基于文本中单个单词查找记录的有效方法。但即便如此,也会有一些限制(例如,搜索“port”一词不一定会返回“sport”之类的记录)。

      MySQL Full Text Search

      【讨论】:

        猜你喜欢
        • 2011-09-07
        • 2017-06-28
        • 1970-01-01
        • 1970-01-01
        • 2016-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多