我正在尝试找出从数据库中提取具有与此类似结构的值的最有效方法:
表格测试:
int id (primary, auto increment)
varchar(50) stuff,
varchar(50) important_stuff;
我需要进行像
这样的查询select * from test where important_stuff like 'prefix%';
整个表的大小约为1000万行,但important_stuff只有大约500-1000个不同的值。我目前的解决方案是索引important_stuff
,但性能不尽如人意。最好是创建一个单独的表格,将不同的important_stuff
与某个ID匹配,该表格将存储在' test'表然后再做
(select id from stuff_lookup where important_stuff like 'prefix%') a join select * from test b where b.stuff_id=a.id
或者这个:
select * from test where stuff_id exists in(select id from stuff_lookup where important_stuff like 'prefix%')
优化这类事情的最佳方法是什么?
答案 0 :(得分:1)
我不是MySQL用户,但我在本地数据库上进行了一些测试。我写了你添加了1000万行,第三列的不同数据加载速度非常快。这些是我的结果。
mysql> describe bigtable;
+-----------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| stuff | varchar(50) | NO | | NULL | |
| important_stuff | varchar(50) | NO | MUL | NULL | |
+-----------------+-------------+------+-----+---------+----------------+
3 rows in set (0.03 sec)
mysql> select count(*) from bigtable;
+----------+
| count(*) |
+----------+
| 10000089 |
+----------+
1 row in set (2.87 sec)
mysql> select count(distinct important_stuff) from bigtable;
+---------------------------------+
| count(distinct important_stuff) |
+---------------------------------+
| 1000 |
+---------------------------------+
1 row in set (0.01 sec)
mysql> select distinct important_stuff from bigtable;
....
| is_987 |
| is_988 |
| is_989 |
| is_99 |
| is_990 |
| is_991 |
| is_992 |
| is_993 |
| is_994 |
| is_995 |
| is_996 |
| is_997 |
| is_998 |
| is_999 |
+-----------------+
1000 rows in set (0.15 sec)
重要信息是我刷新了此表的统计信息(在此操作之前,我需要大约10秒才能加载这些数据)。
mysql> optimize table bigtable;
答案 1 :(得分:1)
innodb_buffer_pool_size
有多大?有多少RAM可用?前者应该是后者的约70%。你会在一分钟内看到为什么我提出这个设置。
根据您建议的3个SELECT,原始的SELECT将与两个复杂的SELECT一样好。在某些其他案例中,复杂的表述可能会更好。
INDEX(important_stuff)
是
select * from test where important_stuff like 'prefix%';
现在,让我们研究一下该查询如何与该索引一起使用:
id
)。 (努力:< = 10次磁盘命中)总工作量:~1010块(最差情况)。
标准旋转磁盘可以处理~100次读/秒。所以。我们正在看10秒钟。
现在,再次运行查询。你猜怎么着;所有这些块现在都在RAM中(缓存在“buffer_pool”中,希望希望足够所有这些块)。它运行不到1秒钟。
OPTIMIZE TABLE
不是必要的!它是不统计信息刷新,而是加速查询的缓存。