Mysql 选择两列的值位于数组中的行

Mysql 选择两列的值位于数组中的行,mysql,sql,Mysql,Sql,我有一张长长的股票价格表,其中包括以下内容: | Date | exchange_code | ticker | price | |------------|---------------------|--------------|-------------| |2020 -01-01 | US | GOOG | XXXXX | 我想知道哪种方法是选择在给定数组中包含成对交换代码和ti

我有一张长长的股票价格表,其中包括以下内容:

|    Date    |    exchange_code    |    ticker    |    price    |
|------------|---------------------|--------------|-------------|
|2020 -01-01 |         US          |    GOOG      |    XXXXX    |
我想知道哪种方法是选择在给定数组中包含成对交换代码和ticker的行的最有效方法

我唯一的想法是添加另一个列,如exchange\u ticker,然后使用查询,如

SELECT * FROM mytable 
WHERE exchange_ticker IN (X,Y,Z);
此外,由于该表相当长,我将在该列上添加一个索引

我相信一定有更好的方法。。。有什么想法吗

谢谢

您可以使用元组:

SELECT *
FROM mytable 
WHERE (exchange, ticker) IN ( (A, X), (B, Y), (C, Z) );
这应该能够利用mytableexchange、ticker上的索引

如果列表已在表中,则可以使用JOIN:


您还需要为此创建索引。

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_代码的基数,差异会变得更加明显

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)
它应该,但不会-至少在8.0之前不会:-
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)