mysql - 500万行表中最长前缀匹配的最佳MYSQL查询

标签 mysql sql

我有一个包含 500 万行的表

CREATE TABLE dummy_table (
            num VARCHAR(16) NOT NULL DEFAULT 0,
            rsid VARCHAR(16) NOT NULL,
            list VARCHAR(128) NOT NULL,
            PRIMARY KEY (num, rsid)
            );  

表中的num字段是某个动态数字的前缀(上面查询中的“123457467890”)。现在我需要获取list 基于numrsid的列,其中num必须是来电号码的最长前缀匹配。为了获取 list 我有一个以下查询:

select list 
from dummy_table 
where '123457467890' like CONCAT(num, '%') 
  and rsid = '123' 
order by LENGTH(num) desc LIMIT 1;

注意:123457467890`:每次我们抛出查询时该数字都会不同

现在的问题是执行这个查询,MYSQL 大约需要 0.80 秒,这对我来说非常长。我需要在一秒钟内抛出超过 1000 个查询。有什么办法可以优化这个查询到这个程度吗?谁能帮助实现这个结果?

最佳答案

我的第一个优化是:
- 添加另一列“长度”
- 在(rsid, length DESC, num)

上添加索引

现在您的查询仅略有不同:
- 从 dummy_table 中选择列表,其中 '123457467890' LIKE CONCAT(num, '%') AND rsid = '123' ORDER BY length DESC LIMIT 1;

但是,通过在索引中包含长度,查询应该能够在第一次命中时停止。

但是...

这始终是一个代价高昂的过程。最坏的情况是您找不到匹配项 - 因此无论如何都必须扫描完整的 (rsid = '123') 记录集。

上述优化不会帮助优化最坏的情况,只能帮助优化最好的情况。 (比赛时间越长,帮助越大,但对于较短的比赛帮助不大。)


你可能被迫做的事情是……
1.创建临时表
2. 在其中插入“1234567890”
3. 在其中插入“123456789”
4. 在其中插入“12345678”
.
.
.
名词在其中插入“1”

此时,临时表中的搜索字符串已具有所有可能的匹配项。

然后您的查询可以使用索引查找。可能会找到 10 个匹配项(在本例中),然后找到其中最长的一个。

-- Index now needs to be (rsid, num, length)

SELECT
  *
FROM
  dummy_table
INNER JOIN
  your_search_table
    ON dummy_table.num = your_search_table.num
WHERE
  rsid = '123'
ORDER BY
  dummy_table.length
LIMIT
  1

关于mysql - 500万行表中最长前缀匹配的最佳MYSQL查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20703660/

相关文章:

mysql 多重内连接复杂度

mysql - 为什么我的 mysql 查询在 JPA 中不起作用?

c++ - Qt MySQL - 创建新表

SQL Server : create manual sort order

mysql - 使用mysql分区表删除优化(MySQL 5.1)

mysql - 表锁 读写 别名

sql - 为什么sql server中每个表只能创建一个聚集索引?

sql - Postgresql 如何以正确的顺序获得此排名顺序

php - 插入 SQL 表或更新记录(如果存在)

php - 如何减少循环时间