我们有三张table users
, stores
以及 store_customer_associations
,其中一个用户可以成为许多客户 stores
.
我曾尝试在主键中放置另一个索引,但没有成功(其他也一样)。
(目前这些是我们在每个表中的索引)
mysql> SHOW INDEXES FROM store_customer_associations;
+-------+------------+-------------------------------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+-------------------------------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| users | 0 | PRIMARY | 1 | id | A | 9386515 | NULL | NULL | | BTREE | | |
| users | 0 | tmp_idx_users_id | 1 | id | A | 9386515 | NULL | NULL | | BTREE | | |
+-------+------------+-------------------------------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
10 rows in set (0.00 sec)
mysql> SHOW INDEXES FROM store_customer_associations;
+-----------------------------+------------+-----------------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------------------------+------------+-----------------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| store_customer_associations | 0 | PRIMARY | 1 | id | A | 51298761 | NULL | NULL | | BTREE | | |
| store_customer_associations | 1 | index_store_customer_associations_on_store_id | 1 | store_id | A | 50096 | NULL | NULL | YES | BTREE | | |
| store_customer_associations | 1 | index_store_customer_associations_on_user_id | 1 | user_id | A | 25649380 | NULL | NULL | YES | BTREE | | |
+-----------------------------+------------+-----------------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.00 sec)
我们使用的是Rails5.1(这是一个很大的Rails4遗留数据库)。
然后我们需要快速查询:
SELECT COUNT(*)
FROM `users`
INNER JOIN `store_customer_associations`
ON `users`.`id` = `store_customer_associations`.`user_id`
WHERE `store_customer_associations`.`store_id` = STORE_ID;
+----------+
| COUNT(*) |
+----------+
| 1997632 |
+----------+
1 row in set (6.64 sec)
mysql> EXPLAIN SELECT COUNT(*)
FROM `users`
INNER JOIN `store_customer_associations`
ON `users`.`id` = `store_customer_associations`.`user_id`
WHERE `store_customer_associations`.`store_id` = STORE_ID;
+------+-------------+-----------------------------+--------+--------------------------------------------------------------------------------------------+-----------------------------------------------+---------+---------------------------------------------------------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------------------------+--------+--------------------------------------------------------------------------------------------+-----------------------------------------------+---------+---------------------------------------------------------+---------+-------------+
| 1 | SIMPLE | store_customer_associations | ref | index_store_customer_associations_on_store_id,index_store_customer_associations_on_user_id | index_store_customer_associations_on_store_id | 5 | const | 4401812 | Using where |
| 1 | SIMPLE | users | eq_ref | PRIMARY,tmp_idx_users_id | PRIMARY | 4 | trustvox_production.store_customer_associations.user_id | 1 | Using index |
+------+-------------+-----------------------------+--------+--------------------------------------------------------------------------------------------+-----------------------------------------------+---------+---------------------------------------------------------+---------+-------------+
2 rows in set (0.00 sec)
更新1
mysql> EXPLAIN SELECT COUNT(*)
FROM `users`
INNER JOIN `store_customer_associations`
ON `users`.`id` = `store_customer_associations`.`user_id`
WHERE `store_customer_associations`.`store_id` = STORE_ID;
+------+-------------+-----------------------------+--------+-------------------------------------------------------------------------------------------------------------+-----------------------------------------------+---------+---------------------------------------------------------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------------------------+--------+-------------------------------------------------------------------------------------------------------------+-----------------------------------------------+---------+---------------------------------------------------------+---------+-------------+
| 1 | SIMPLE | store_customer_associations | ref | index_store_customer_associations_on_store_id,index_store_customer_associations_on_user_id,user_id_store_id | index_store_customer_associations_on_store_id | 5 | const | 4401812 | Using where |
| 1 | SIMPLE | users | eq_ref | PRIMARY,tmp_idx_users_id | PRIMARY | 4 | trustvox_production.store_customer_associations.user_id | 1 | Using index |
+------+-------------+-----------------------------+--------+-------------------------------------------------------------------------------------------------------------+-----------------------------------------------+---------+---------------------------------------------------------+---------+-------------+
2 rows in set (0.00 sec)
更新2
mysql> SELECT COUNT(*)
FROM users
INNER JOIN store_customer_associations
FORCE INDEX FOR JOIN (PRIMARY, user_id_store_id)
ON users.id = store_customer_associations.user_id
WHERE store_customer_associations.store_id = STORE_ID;
+----------+
| COUNT(*) |
+----------+
| 1997632 |
+----------+
1 row in set (28.90 sec)
mysql> EXPLAIN SELECT COUNT(*)
FROM users
INNER JOIN store_customer_associations
FORCE INDEX FOR JOIN (PRIMARY, user_id_store_id)
ON users.id = store_customer_associations.user_id
WHERE store_customer_associations.store_id = STORE_ID;
+------+-------------+-----------------------------+-------+--------------------------+------------------+---------+------------------------------------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------------------------+-------+--------------------------+------------------+---------+------------------------------------+---------+-------------+
| 1 | SIMPLE | users | index | PRIMARY,tmp_idx_users_id | tmp_idx_users_id | 4 | NULL | 8675689 | Using index |
| 1 | SIMPLE | store_customer_associations | ref | user_id_store_id | user_id_store_id | 10 | trustvox_production.users.id,const | 1 | Using index |
+------+-------------+-----------------------------+-------+--------------------------+------------------+---------+------------------------------------+---------+-------------+
2 rows in set (0.00 sec)
mysql>
更新3
mysql> EXPLAIN SELECT COUNT(*)
FROM users
INNER JOIN
( SELECT *
FROM store_customer_associations
WHERE store_id = 75856
) sca ON users.id = sca.user_id;
+------+-------------+-----------------------------+--------+-------------------------------------------------------------------------------------------------------------+-----------------------------------------------+---------+---------------------------------------------------------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------------------------+--------+-------------------------------------------------------------------------------------------------------------+-----------------------------------------------+---------+---------------------------------------------------------+---------+-------------+
| 1 | SIMPLE | store_customer_associations | ref | index_store_customer_associations_on_store_id,index_store_customer_associations_on_user_id,user_id_store_id | index_store_customer_associations_on_store_id | 5 | const | 4401812 | Using where |
| 1 | SIMPLE | users | eq_ref | PRIMARY,tmp_idx_users_id | PRIMARY | 4 | trustvox_production.store_customer_associations.user_id | 1 | Using index |
+------+-------------+-----------------------------+--------+-------------------------------------------------------------------------------------------------------------+-----------------------------------------------+---------+---------------------------------------------------------+---------+-------------+
更新4
mysql> ALTER TABLE store_customer_associations DROP INDEX index_store_customer_associations_on_store_id;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE store_customer_associations DROP INDEX index_store_customer_associations_on_user_id;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> CREATE INDEX index_on_store_id_and_user_id ON store_customer_associations (store_id, user_id);
Query OK, 0 rows affected (45.95 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> CREATE INDEX index_store_customer_associations_on_user_id ON store_customer_associations(user_id);
Query OK, 0 rows affected (33.06 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> CREATE INDEX index_store_customer_associations_on_store_id ON store_customer_associations(store_id);
Query OK, 0 rows affected (38.58 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW INDEXES FROM store_customer_associations;
+-----------------------------+------------+-----------------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------------------------+------------+-----------------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| store_customer_associations | 0 | PRIMARY | 1 | id | A | 10305620 | NULL | NULL | | BTREE | | |
| store_customer_associations | 1 | index_on_store_id_and_user_id | 1 | store_id | A | 8244 | NULL | NULL | YES | BTREE | | |
| store_customer_associations | 1 | index_on_store_id_and_user_id | 2 | user_id | A | 10305620 | NULL | NULL | YES | BTREE | | |
| store_customer_associations | 1 | index_store_customer_associations_on_user_id | 1 | user_id | A | 10305620 | NULL | NULL | YES | BTREE | | |
| store_customer_associations | 1 | index_store_customer_associations_on_store_id | 1 | store_id | A | 6424 | NULL | NULL | YES | BTREE | | |
+-----------------------------+------------+-----------------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
5 rows in set (0.00 sec)
2条答案
按热度按时间ej83mcc01#
sdnqo3pr2#
你需要为存储\游标表\关联的2个参数建立索引,因为在查询中索引不是因为where部分。
我应该帮你
例子