我有一张这样的表:
+--------------+--------------+------+-----+--------------------------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+--------------------------------------+-------+
| id | varchar(36) | NO | PRI | NULL | |
| provider_id | varchar(36) | YES | MUL | 00000000-0000-0000-0000-000000000000 | |
| to_provider | int(11) | NO | | NULL | |
| to_customer | int(11) | NO | | NULL | |
| published_at | datetime | NO | | NULL | |
| expired_at | datetime | NO | | NULL | |
| title | varchar(512) | NO | | NULL | |
| content | text | YES | | NULL | |
| created_at | datetime | NO | | NULL | |
| created_by | varchar(255) | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
| updated_by | varchar(255) | YES | | NULL | |
| deleted_at | datetime | YES | | NULL | |
| deleted_by | varchar(255) | YES | | NULL | |
+--------------+--------------+------+-----+--------------------------------------+-------+
我创建了一个这样的索引:
+---------------+------------+-------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------------+------------+-------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| announcements | 0 | PRIMARY | 1 | id | A | 76184 | NULL | NULL | | BTREE | | |
| announcements | 1 | idx_announcements | 1 | provider_id | A | 7 | NULL | NULL | YES | BTREE | | |
| announcements | 1 | idx_announcements | 2 | deleted_at | A | 7 | NULL | NULL | YES | BTREE | | |
| announcements | 1 | idx_announcements | 3 | published_at | A | 7 | NULL | NULL | | BTREE | | |
| announcements | 1 | idx_announcements | 4 | to_provider | A | 7 | NULL | NULL | | BTREE | | |
| announcements | 1 | idx_announcements | 5 | to_customer | A | 7 | NULL | NULL | | BTREE | | |
| announcements | 1 | idx_announcements | 6 | expired_at | A | 7 | NULL | NULL | | BTREE | | |
| announcements | 1 | idx_announcements | 7 | updated_at | A | 7 | NULL | NULL | YES | BTREE | | |
+---------------+------------+-------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
当我跑步时
MariaDB [table_name]> EXPLAIN SELECT COUNT(*) FROM `announcements` `t` WHERE (((`t`.provider_id = "3c5e63df-cb9b-f5a8-4eaf-7ed0061b797d") OR (provider_id="00000000-0000-0000-0000-000000000000")) AND (`t`.deleted_at IS NULL))AND(((published_at <= "2015-07-17 14:54:36") AND ( to_provider IN (1))) AND (to_customer IN (0, 1)));
+------+-------------+-------+-------+-------------------+-------------------+---------+------+-------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+-------------------+-------------------+---------+------+-------+--------------------------+
| 1 | SIMPLE | t | range | idx_announcements | idx_announcements | 64 | NULL | 38093 | Using where; Using index |
+------+-------------+-------+-------+-------------------+-------------------+---------+------+-------+--------------------------+
看,我可以使用索引,但是当我运行
时MariaDB [table_name]> EXPLAIN SELECT * FROM `announcements` `t` WHERE (((`t`.provider_id = "3c5e63df-cb9b-f5a8-4eaf-7ed0061b797d") OR (provider_id="00000000-0000-0000-0000-000000000000")) AND (`t`.deleted_at IS NULL))AND(((published_at <= "2015-07-17 14:54:36") AND ( to_provider IN (1))) AND (to_customer IN (0, 1)));
+------+-------------+-------+------+-------------------+------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+-------------------+------+---------+------+-------+-------------+
| 1 | SIMPLE | t | ALL | idx_announcements | NULL | NULL | NULL | 76184 | Using where |
+------+-------------+-------+------+-------------------+------+---------+------+-------+-------------+
看,键是null!我真的不明白。使用相同的地方,但“select *”不能使用索引。
任何人都可以告诉我?
哦,我有一个像这样的SQL
SELECT * FROM `announcements` `t`
WHERE
(((`t`.provider_id = :provider_id) OR (provider_id=:ycp0)) AND (`t`.deleted_at IS NULL))
AND (published_at<="2015-07-17 16:58:57" AND (to_provider IN(1) AND to_customer IN (0,1))
AND expired_at>="2015-07-17 16:58:57"
AND (updated_at > "2015-07-10 16:58:57" || published_at > "2015-07-10 16:58:57" ))
ORDER BY updated_at DESC LIMIT 10
如何为此查询创建索引?我在“OR”上遇到了问题~~~
答案 0 :(得分:0)
只有在select的一个表的任何实例上使用单个索引来解决MySQL问题的一种方法是将select拆分为2并将它们组合在一起。
例如,对于您的select,如果updated_at
和published_at
都是有用的索引,那么您可以允许MySQL使用它们,如下所示: -
SELECT *
FROM announcements t
WHERE t.provider_id IN ( :provider_id, :ycp0)
AND t.deleted_at IS NULL
AND published_at<="2015-07-17 16:58:57"
AND to_provider IN(1)
AND to_customer IN (0,1)
AND expired_at>="2015-07-17 16:58:57"
AND updated_at > "2015-07-10 16:58:57"
UNION
SELECT *
FROM announcements t
WHERE t.provider_id IN ( :provider_id, :ycp0)
AND t.deleted_at IS NULL
AND published_at<="2015-07-17 16:58:57"
AND to_provider IN(1)
AND to_customer IN (0,1)
AND expired_at>="2015-07-17 16:58:57"
AND published_at > "2015-07-10 16:58:57"
ORDER BY updated_at DESC LIMIT 10