首页 > 解决方案 > 关于select ... in的sql性能

问题描述

mysql 5.7.21

我使用池连接数据库并运行 SQL

let mysql = require('mysql');
let pool = mysql.createPool(db);
pool.getConnection((err, conn) => {
      if(err){
        ...
      }else{
        console.log('allConnections:' + pool._allConnections.length);
        let q = conn.query(sql, val, (err, rows,fields) => {
        ...

我有一张包含大约 1,000,000 条记录的表。我写了一个选择来检查记录。

select * from tableA where trackingNo in (?)

我将通过数组参数发送 trackingNo。trackingNo 的数量在 20000 左右。这意味着数组的长度在 20000 左右。

我为 trackingNo 列建立了索引。(trackingNo列为varchar类型,不唯一,可以为null、空白和所有可能的值)

问题是,我发现得到结果大约需要 5 分钟!这里的 5 分钟意味着纯粹的后端 sql 处理时间。我认为在 1,000,000 条记录中匹配 20000 条记录太慢了。您对 select.. in 有什么建议吗?

解释 SQL:

id  select_type table   partitions  type    possible_keys          key    key_len   ref   rows   filtered   Extra
1   SIMPLE      tableA  null        ALL     table_tracking_no_idx  null   null      null  999507    50      Using where

标签: mysqlsql

解决方案


您可以考虑使用要匹配的跟踪号填充表格。然后,您可以使用内部联接而不是当前WHERE IN方法:

SELECT *
FROM tableA a
INNER JOIN tbl b
    ON a.trackingNo = b.trackingNo;

tbl这样做的好处是您可以对列上的新表进行索引,trackingNo从而使连接查找非常快。

这假设tbl将有一个trackingNo包含您需要考虑的 20K+ 值的列。


推荐阅读