结合两个非常快的查询时MySQL慢查询

标签 mysql sql performance

我有两个运行速度非常快的 MySQL 查询,但是当我组合它们时,新查询非常慢。

快速(<1 秒,15 个结果):

SELECT DISTINCT 
Id, Name, Company_Id
FROM people
where Company_Id in (5295, 1834)
and match(Locations) against('austin')

快速(<1 秒,2970 个结果):

select distinct Company_Id from technologies
    where match(Name) against('elastic')
      and Company_Id is not null

当我像这样将两者结合起来时:

SELECT DISTINCT Id, Name, Company_Id
FROM people
where Company_Id in
    ( select Company_Id from technologies
        where match(Name) against('elastic')
          and Company_Id is not null
    )
  and match(Locations) against('austin')

结果查询需要 2 多分钟才能完成。它命中了 278 行。

我已经尝试用几种方法重写慢速查询。另一个例子是这样的:

SELECT DISTINCT 
`Extent1`.`Id`, `Extent1`.`Name`, `Extent1`.`Company_Id`
FROM `people` AS `Extent1` 
INNER JOIN `technologies` AS `Extent2`
     ON (`Extent1`.`Company_Id` = `Extent2`.`Company_Id`)
WHERE (`Extent1`.`Company_Id` IS NOT NULL) 
 AND ((match(`Extent1`.`Locations`) against('austin')) 
 AND  (match(`Extent2`.`Name`) against('elastic')))

我在 Windows 上使用 MySQL 5.7。我在名称和位置列上有全文索引。我的 InnoDB 缓冲区使用率从未超过 40%。我尝试使用 MySQL Workbench 查看执行计划,但它显示“Explain data not available for statement”

如果您看到任何我可以改进或尝试的地方,请告诉我。谢谢。

最佳答案

IN ( SELECT ... )优化不佳,至少在旧版本的 MySQL 中是这样。您使用的是什么版本?

使用 FULLTEXT 时索引 ( MATCH... ),如果可能,该部分首先执行。这是因为 FT 查找几乎总是比其他任何事情都快。

但是当使用两个全文查询时,它会选择一个,然后不能对另一个使用全文。

这是一种可能的解决方法:

  • 有一个额外的搜索表。它包括 NameLocations
  • FULLTEXT(Name, Locations)
  • MATCH (Name, Locations) AGAINST ('+austin +elastic' IN BOOLEAN MODE)

如有必要,AND用一些东西来验证它不是,例如,找到一个叫“奥斯汀”的人。

另一种可能性:

5.7(或 5.6?)可能能够通过在子查询上创建索引来优化它:

SELECT ...
    FROM ( SELECT Company_Id FROM ... MATCH(Name) ... ) AS x
    JOIN ( SELECT Company_Id FROM ... MATCH(Locations) ... ) AS y
        USING(Company_id);

提供 EXPLAIN ;我希望看到 <auto-key> .

测试一下。如果它“快”,那么您可能需要添加另一个 JOIN和/或 WHERE . (我不清楚您的最终查询需要是什么。)

关于结合两个非常快的查询时MySQL慢查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42097593/

相关文章:

python - 如何加速代码来解决位删除难题

php - 尽管在本地服务器中正常工作,但 cpanel 中的 codeigniter Web 应用程序出现错误

C# 'Extent1.UserId' 中的未知列 'field list'

mysql - Zend_Db_Table、JOIN 和 mysql 表达式在一个查询中?

mysql - 接口(interface)错误: 2013: Lost connection to MySQL server during query

c++ - 附加条件语句使程序更快

php - 优化查询SQL

MySQL - 在初始 auto_increment 值之前保留 ID

mysql - SQL GROUP_CONCAT 拆分成不同的列

performance - 如何删除矩阵 A 的那些行,这些行在 Matlab 的指定列中与矩阵 B 具有相等的值?