mysql - 我如何确保此查询坚持索引?

标签 mysql sql indexing

我有一个包含两个表的数据库。一个包含帐户,另一个包含超过 200 万行,其中包含地址及其坐标。显然,对于如此多的行,任何时候未充分利用索引的查询运行都将花费几分钟甚至数小时才能完成。不幸的是,目前我的一个查询就是这种情况:

SELECT
    addr.`Linje-ID` as lineid,
    addr.`Sluttbruker` as companyname,
    addr.`Gate` as street,
    addr.`Husnr` as housenr,
    addr.`Postnr` as zip,
    addr.`Poststed` as location,
    loc.`UX_KOORDINAT` as coord_x,
    loc.`UY_KOORDINAT` as coord_y,
    loc.`ADRESSE_ID` as addr_id

FROM
    addresses addr INNER JOIN
    locationdata loc ON
        loc.`POSTSTED` = addr.`Poststed` AND
        loc.`POST_NR` = addr.`Postnr` AND
        loc.`GATENAVN` = addr.`Gate` AND
        loc.`HUSNUMMER` = addr.`Husnr`

GROUP BY
    addr.`Linje-ID`

locationdata 表有一个主索引 id 以及一个定义为 (POSTSTED, POST_NR, GATENAVN, HUSNUMMER) 的索引。按照该顺序使用这些列从表中获取行的速度非常快。但是,上面的查询必须取消,因为它花费的时间太长(>15 分钟)。

由于我的 MySQL 客户端 (HeidiSQL) 在执行查询时卡住,强制关闭应用程序并在每次尝试解决此问题时重新开始变得非常乏味,所以我在这里寻求帮助。

只是为了测试,“addresses”表目前只包含一行。

谁能确定为什么这个查询“从不”完成?


这是我被要求的 EXPLAIN 结果 http://pastebin.com/qWdQhdv5

您应该复制内容并将其粘贴到一个更大的容器中,因为它会换行。


编辑:我编辑了查询以反射(reflect)您的一些回复。它仍然使用了 300 多秒,而它本不应需要 1 秒。

最佳答案

首先,我会从 loc.GATENAVN = UPPER(addr.Gate) 中删除 upper,因为这个子句已经在 case insensitive mode 中搜索了.

关于mysql - 我如何确保此查询坚持索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5360149/

相关文章:

sql - 如何使用一个 select 语句的结果作为另一个 select 语句的列?

python - 在数据库中实现匹配

java - 如何在cloudant中构建类来管理使用JSON文档的搜索索引查询的输出

c# - 如何有效地索引文件?

mysql_fetch_array() 问题

PHPExcel 发生超时

mysql - Zend Framework中自动引用MySQL查询疑惑

sql - 与当前行的属性值相关的SQL窗口函数中的窗口框如何表示?

sql - 带日期时间的 WHERE 子句的索引等

PHP MYSQL - 显示多线程评论不起作用