Выберите строки, в которых значения двух столбцов находятся в массиве - PullRequest
0 голосов
/ 15 марта 2020

У меня есть длинная таблица с ценами на акции, которая, помимо прочего, включает в себя следующее:

|    Date    |    exchange_code    |    ticker    |    price    |
|------------|---------------------|--------------|-------------|
|2020 -01-01 |         US          |    GOOG      |    XXXXX    |

Я хотел бы знать, какой самый эффективный способ выбрать строки, где пары (exchange_code и ticker ) включены в данный массив.

Единственная идея, которую я имею, состоит в том, чтобы добавить еще один столбец, например exchange_ticker, а затем использовать запрос, подобный

SELECT * FROM mytable 
WHERE exchange_ticker IN (X,Y,Z);

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

Я уверен, что должен быть лучший способ ... любая идея?

Спасибо!

Ответы [ 2 ]

1 голос
/ 15 марта 2020

Вы можете использовать кортежи:

SELECT *
FROM mytable 
WHERE (exchange, ticker) IN ( (A, X), (B, Y), (C, Z) );

Это позволит использовать индекс на mytable(exchange, ticker).

Если список уже находится в таблице, вы можете использовать JOIN:

select t.*
fro mytable t join
    list l
    using (exchange, ticker);

Вам также нужен индекс для этого.

0 голосов
/ 15 марта 2020
Идея

GL хороша, но (по крайней мере, в старых версиях MySQL) она не сильно поможет ...

mysql> EXPLAIN
    -> SELECT *
    -> FROM mytable
    -> WHERE (exchange_code, ticker) IN ( ('US','MOBI'), ('US','TESL'), ('UK','BP') );
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | mytable | ALL  | NULL          | NULL | NULL    | NULL |  147 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

mysql> EXPLAIN
    -> SELECT *
    ->   FROM mytable
    ->  WHERE (exchange_code = 'US' AND ticker = 'MOBI')
    ->     OR (exchange_code = 'US' AND ticker = 'TESL')
    ->     OR (exchange_code = 'UK' AND ticker = 'BP')
    ->     ;
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | mytable | ALL  | exchange_code | NULL | NULL    | NULL |  147 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.6.21    |
+-----------+

Второй запрос не использует индекс, потому что мой набор данных крошечный. Первый запрос даже не находит индекс.

Если я немного увеличу размер набора данных (и количество элементов exchange_code), разница станет более заметной.

mysql> EXPLAIN
    -> SELECT *
    ->   FROM mytable
    ->  WHERE (exchange_code = 'US' AND ticker = 'MOBI')
    ->     OR (exchange_code = 'US' AND ticker = 'TESL')
    ->     OR (exchange_code = 'UK' AND ticker = 'BP')
    ->     ;
+----+-------------+---------+-------+---------------+---------------+---------+------+------+-----------------------+
| id | select_type | table   | type  | possible_keys | key           | key_len | ref  | rows | Extra                 |
+----+-------------+---------+-------+---------------+---------------+---------+------+------+-----------------------+
|  1 | SIMPLE      | mytable | range | exchange_code | exchange_code | 16      | NULL |   43 | Using index condition |
+----+-------------+---------+-------+---------------+---------------+---------+------+------+-----------------------+
1 row in set (0.00 sec)

mysql> EXPLAIN
    -> SELECT *
    -> FROM mytable
    -> WHERE (exchange_code, ticker) IN ( ('US','MOBI'), ('US','TESL'), ('UK','BP') );
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | mytable | ALL  | NULL          | NULL | NULL    | NULL | 2352 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...