SQL Проверка, если значение в таблице находится в диапазоне 2 столбцов в другой таблице - PullRequest
1 голос
/ 29 мая 2019

Я пытаюсь проверить, находится ли значение в TABLE_1 в диапазоне, основанном на 2 столбцах в TABLE_2. Я могу выполнить на основе ответа, предоставленного в вопросе SQL: Проверка, если число в диапазоне нескольких диапазонов , однако, когда я использовал этот метод с большим набором данных (~ 40K строк в обеих таблицах), это максимизирует ЦП на моем сервере SQL и запрос занимает более 3 минут. Есть ли способ оптимизировать этот запрос и ограничить использование процессора этим запросом? Если нет, есть ли альтернативный запрос, который может быть более эффективным.

TABLE_1:

mysql> SELECT * FROM TABLE_1;
+----+---------+-------+
| ID | FRUIT   | COUNT |
+----+---------+-------+
|  1 | Apples  |  2314 |
|  2 | Oranges |  3412 |
|  3 | Oranges |  1296 |
|  4 | Apples  |  2230 |
|  5 | Apples  |  5293 |
|  6 | Oranges |  1994 |
+----+---------+-------+
6 rows in set (0.00 sec)

TABLE_2:

mysql> SELECT * FROM TABLE_2;
+----+---------+-------------+-----------+
| ID | FRUIT   | START_RANGE | END_RANGE |
+----+---------+-------------+-----------+
|  1 | Apples  |        2300 |      2400 |
|  2 | Apples  |        7000 |      8000 |
|  3 | Oranges |        1296 |      1296 |
|  4 | Apples  |        5000 |      6000 |
|  5 | Oranges |        9000 |      9999 |
|  6 | Oranges |        8000 |      9000 |
+----+---------+-------------+-----------+

Запрос:

SELECT *
FROM TABLE_1
WHERE NOT EXISTS (SELECT 1 FROM TABLE_2
                  WHERE TABLE_1.FRUIT = TABLE_2.FRUIT 
                  AND TABLE_1.COUNT BETWEEN TABLE_2.START_RANGE AND TABLE_2.END_RANGE);

Выход:

+----+---------+-------+
| ID | FRUIT   | COUNT |
+----+---------+-------+
|  2 | Oranges |  3412 |
|  4 | Apples  |  2230 |
|  6 | Oranges |  1994 |
+----+---------+-------+
3 rows in set (0.00 sec)

Ответы [ 3 ]

0 голосов
/ 29 мая 2019

not exists, вероятно, самая эффективная версия, но вы можете попробовать left join эквивалент:

select table1.*
from Table1
left join table2
on table1.fruit = table2.fruit
and table1.count between table2.start_range and table2.end_range
where table2.id is null
0 голосов
/ 29 мая 2019

Помимо добавления индекса на table_2.fruit (как уже предлагал @Gordon), вы можете попробовать следующее:

SELECT *
FROM   table_1
WHERE  id NOT IN (SELECT tab1.id
                  FROM   table_1 tab1
                  JOIN   table_2 tab2
                    ON   tab1.fruit = tab2.fruit
                   AND   tab1.count BETWEEN tab2.start_range AND tab2.end_range);

Это, конечно, предполагает, что ID если первичный ключ.

0 голосов
/ 29 мая 2019

Это ваш запрос:

SELECT *
FROM TABLE_1
WHERE NOT EXISTS (SELECT 1 FROM TABLE_2
                  WHERE TABLE_1.FRUIT = TABLE_2.FRUIT AND
                        TABLE_1.COUNT BETWEEN TABLE_2.START_RANGE AND TABLE_2.END_RANGE);

Для повышения производительности начните с индекса на TABLE_2(FRUIT, START_RANGE, END_RANGE).

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