О производительности sql select ... in - PullRequest
0 голосов
/ 10 июня 2019

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. Я думаю, что это слишком медленно, чтобы сопоставить 20000 записей в 1 000 000 записей. Есть ли у вас предложения для выбора .. в?

Объясните 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

Ответы [ 2 ]

2 голосов
/ 10 июня 2019

Вы могли бы рассмотреть заполнение таблицы с номерами отслеживания, которые вы хотите сопоставить. Тогда вы можете использовать внутреннее соединение вместо вашего текущего подхода WHERE IN:

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

Это имеет то преимущество, что вы можете индексировать новую таблицу tbl в столбце trackingNo, чтобы сделать поиск соединения очень быстрым.

Предполагается, что tbl будет иметь один столбец trackingNo, который содержит значения 20K +, которые необходимо учитывать.

0 голосов
/ 10 июня 2019

MySQL создает двоичное дерево поиска для списков IN, которые состоят из констант.Как объясняется в документации :

Если все значения являются константами, они оцениваются в соответствии с типом expr и сортируются.Поиск элемента затем выполняется с помощью бинарного поиска.Это означает, что IN очень быстр, если список значений IN полностью состоит из констант.

Как правило, создание отдельной таблицы с константами не обеспечивает значительного улучшения производительности.

Я полагаю, что с совместимостью типов могут быть некоторые тонкие проблемы, такие как сопоставления,что мешает этому процессу.

Этот тип запроса, вероятно, требует полного сканирования таблицы.Если строки широкие, то сочетание сканирования и возврата данных может быть причиной производительности.Я согласен, что пять минут - это много времени, но это может быть полностью связано с сетевым соединением между приложением / графическим интерфейсом пользователя и базой данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...