我有一个表,以每个页面的JSON格式存储标签。当前表有大约1,000,000条记录。 我跑的时候
SELECT COUNT(*) FROM alltags WHERE tagtype = 'pages' AND JSON_SEARCH(tags, 'one', 'Hampden') IS NOT NULL;
查询大约需要20秒
+----------+
| COUNT(*) |
+----------+
| 23500 |
+----------+
1 row in set (19.20 sec)
无论我使用InnoDB还是MyISAM引擎,查询都很慢。 我为tagtype,tags和tagtype索引了标签列。我需要分页的确切结果数。有没有办法加快SELECT COUNT查询?选择实际数据非常快。
SELECT id FROM alltags WHERE tagtype = 'pages' AND JSON_SEARCH(tags, 'one', 'Hampden') IS NOT NULL LIMIT 0,10;
+------+
| id |
+------+
| 5072 |
| 5075 |
| 5078 |
| 5081 |
| 5084 |
| 5087 |
| 5090 |
| 5093 |
| 5096 |
| 5099 |
+------+
10 rows in set (0.01 sec)
这些是索引
SHOW INDEX FROM alltags;
+---------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| alltags | 0 | PRIMARY | 1 | id | A | 896649 | NULL | NULL | | BTREE | | |
| alltags | 1 | tagtype | 1 | tagtype | A | 2 | NULL | NULL | | BTREE | | |
| alltags | 1 | keyword | 1 | keyword | A | 33 | NULL | NULL | | BTREE | | |
| alltags | 1 | tags | 1 | tags | A | 89665 | NULL | NULL | YES | BTREE | | |
+---------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
EXPLAIN结果:
选择数据
EXPLAIN SELECT id FROM alltags WHERE tagtype = 'pages' AND JSON_SEARCH(tags, 'one', 'Hampden') IS NOT NULL;
+----+-------------+---------+------------+------+---------------+---------+---------+-------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+---------+---------+-------+--------+----------+-------------+
| 1 | SIMPLE | alltags | NULL | ref | tagtype | tagtype | 7 | const | 892372 | 100.00 | Using where |
+----+-------------+---------+------------+------+---------------+---------+---------+-------+--------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
选择计数
EXPLAIN SELECT COUNT(*) FROM alltags WHERE tagtype = 'pages' AND JSON_SEARCH(tags, 'one', 'Hampden') IS NOT NULL;
+----+-------------+---------+------------+------+---------------+---------+---------+-------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+---------+---------+-------+--------+----------+-------------+
| 1 | SIMPLE | alltags | NULL | ref | tagtype | tagtype | 7 | const | 892372 | 100.00 | Using where |
+----+-------------+---------+------------+------+---------------+---------+---------+-------+--------+----------+-------------+
1 row in set, 1 warning (0.00 sec)