我有一个大约有600万行的表,并且有很多列包含大量数据。
我想在此表上实现搜索功能,主要基于创建行时的日期范围和其他一些列。
不需要其他表,因此不存在查询中的联接问题。另外,我在日期列和其他相关列上实现了索引。
如果我搜索大范围,考虑到表格的行数,搜索仍需要很长时间。我已将key_buffer_size增加到1G,并将mysql_query_cache增加到500M。
我想知道是否,
我希望在增加RAM或CPU之前探索所有选项。
更新:
以下是更多详情
CPU:Intel Quadcore 内存:4GB 操作系统:CentOS
+-----------------------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------------+---------------+------+-----+---------+----------------+
| deal_id | int(11) | NO | PRI | NULL | auto_increment |
| deal_group_id | int(11) | NO | PRI | NULL | |
| site_id | int(11) | YES | MUL | NULL | |
| datetime | char(14) | YES | MUL | NULL | |
| deal_category | varchar(200) | YES | MUL | NULL | |
| vendor_name | varchar(200) | YES | | NULL | |
| area | varchar(200) | YES | MUL | NULL | |
| address | text | YES | | NULL | |
| country_code | varchar(5) | NO | MUL | NULL | |
| expired | int(1) | NO | | 0 | |
| type | varchar(20) | NO | | REGULAR | |
| pn_id | int(11) | NO | | 0 | |
+-----------------------------+---------------+------+-----+---------+----------------+
以上是架构。在where子句中,使用范围datetime
,deal_category
,vendor_name
in和country_code
的组合。所有都被编入索引。以下是一个示例查询
SELECT distinct t.deal_id, t.deal_group_id, t.site_name, UNIX_TIMESTAMP(t.datetime) as datetime, t.deal_category as deal_category, t.vendor_name, t.area as area, t.country_code FROM table t WHERE 1 AND t.country_code = 'US' AND datetime BETWEEN '20110601' AND '20120303' limit 10;
我已将innodb_buffer_pool_size
增加到大约75%,它提高了某些查询的效果,但如果包含所有过滤器,仍会花费大量时间。
以下是my.cnf文件设置,
query_cache_size=500M
max_allowed_packet= 1G
innodb_buffer_pool_size = 3G
key_buffer_size = 1G
这张桌子非常繁忙,每分钟都有数百封写入。
希望这能给出更清晰的画面。
更新更新
下面是表格中的解释输出和索引,
+----+-------------+-------+------+-----------------------+--------------+---------+-------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+-----------------------+--------------+---------+-------+--------+-------------+
| 1 | SIMPLE | t | ref | country_code,datetime | country_code | 17 | const | 521556 | Using where |
+----+-------------+-------+------+-----------------------+--------------+---------+-------+--------+-------------+
索引:
+-------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
| table | 0 | PRIMARY | 1 | deal_id | A | 5810775 | NULL | NULL | | BTREE | |
| table | 0 | PRIMARY | 2 | deal_group_id | A | 5810775 | NULL | NULL | | BTREE | |
| table | 1 | site_id | 1 | site_id | A | 2109 | NULL | NULL | YES | BTREE | |
| table | 1 | area | 1 | area | A | 18927 | NULL | NULL | YES | BTREE | |
| table | 1 | country_code | 1 | country_code | A | 20 | NULL | NULL | | BTREE | |
| table | 1 | deal_group_id | 1 | deal_group_id | A | 1936925 | NULL | NULL | | BTREE | |
| table | 1 | deal_category | 1 | deal_category | A | 20 | NULL | NULL | YES | BTREE | |
| table | 1 | datetime | 1 | datetime | A | 5810775 | NULL | NULL | YES | BTREE | |
+-------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
由于
答案 0 :(得分:3)
对于运行Innodb的数据库,您需要将innodb_buffer_pool_size的值增加到专用服务器上大约70-80%的可用RAM,以便尽可能多的数据适合内存
创建一个包含您要在
使用LIKE%值%搜索不使用索引
要进行其他调整,您需要提供有关您将要执行的架构和搜索的更多信息
删除WHERE子句中的“1 AND”比较
将“20110601”和“20120303”之间的日期时间更改为DATE(日期时间)STR_TO_DATE('20110601','%Y%m%d')和STR_TO_DATE('20120303','%Y%m%)之间的日期时间d')。我假设datetime字段包含MySQL格式的日期
考虑将日期时间字段从char(14)更改为datetime字段以便更快地进行计算
如果country_code列只有2位数的国家/地区代码,请考虑将其大小更改为char(2)
在deal_id列之前删除DISTINCT,这是一个自动增量和主键