调整mysql服务器进行单个大表查询

时间:2014-05-08 12:13:15

标签: mysql innodb

我有一个非常特殊的用例。我在一个单独的VM上有一个我的生产数据库(MySQL 5.5.29,InnoDB)的副本(我刚刚把8GB的ram扔到了)并且只需要一个查询就需要一个结果,这需要很长时间。

这是查询:

select *
from bew 
inner join bewa on bewa.id = bew.id
inner join sa on bew.sa_id = sa.id
inner join revinfo ri on bewa.rev = ri.id
where sa.vp_id = 6
  and bewa.prio is not null
  and bewa.rev > 0
  and bew.person_id > 0
order by bew.person_id, bewa.rev, bewa.prio

这些是列类型:

bew.id           bigint(20)       [PRIMARY KEY, NOT NULL]
bew.person_id    bigint(20)       [(FOREIGN) KEY, NOT NULL - index: fk_bew_person26]
bew.sa_id        bigint(20)       [(FOREIGN) KEY, NOT NULL - index: fk_bew_sa27]
bewa.id          bigint(20)       [NOT NULL (bewa.id, bewa.rev) = PRIMARY KEY]
bewa.rev         bigint(20)       [NOT NULL (bewa.id, bewa.rev) = PRIMARY KEY, (FOREIGN) KEY - index: fk_bew_aud_revinfo28]
bewa.prio        int(11)          [index: tmp_idx_bewa_prio]
ri.id            bigint(20)       [PRIMARY KEY, NOT NULL]
sa.id            bigint(20)       [PRIMARY KEY, NOT NULL]
sa.vp_id         bigint(20)       [(FOREIGN) KEY, NOT NULL - index: fk_sa_vp141]

上面的所有列都被索引为PRIMARY KEY或单列索引。 到目前为止还没有复合索引(我尝试了一些,但计划没有改变,所以我再次删除了它们。)

还有一些数字:

select count(*) from sa where sa.vp_id = 6;
> 179

select count(*) from bew;
> 240808

select count(*) from bew 
inner join sa on bew.sa_id = sa.id 
where sa.vp_id = 6 and bew.person_id > 0;
> 199955

select count(*) from bewa
> 5126493

select count(*)
from bew 
inner join bewa on bewa.id = bew.id
inner join sa on bew.sa_id = sa.id
inner join revinfo ri on bewa.rev = ri.id
where sa.vp_id = 6
  and bewa.prio is not null
  and bewa.rev > 0
  and bew.person_id > 0;
> (still counting after 10 min ... :( )

这是解释输出:

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: bew
         type: ALL
possible_keys: PRIMARY,fk_bew_person26,fk_bew_sa27
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 241594
        Extra: Using where; Using temporary; Using filesort
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: sa
         type: eq_ref
possible_keys: PRIMARY,fk_sa_vp141
          key: PRIMARY
      key_len: 8
          ref: bew.sa_id
         rows: 1
        Extra: Using where
*************************** 3. row ***************************
           id: 1
  select_type: SIMPLE
        table: bewa
         type: ref
possible_keys: PRIMARY,fk_bew_aud_revinfo28,tmp_idx_bewa_prio
          key: PRIMARY
      key_len: 8
          ref: bew.id
         rows: 6
        Extra: Using where
*************************** 4. row ***************************
           id: 1
  select_type: SIMPLE
        table: ri
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 8
          ref: bewa.REV
         rows: 1
        Extra: 

我没有太多可以做的事情来实际优化SQL(它是相当多的数据,我需要它排序......)因为我只需要运行它一次,这无关紧要,无论如何。

因此,请将此查询作为我的实际更广泛问题的示例:

如何针对此类(报告)查询调整my.cnf文件中的设置,使其运行速度比现在快?实际上,我想要的是为单个会话提供尽可能多的内存来执行单个查询。我不需要查询缓存或良好的多用户性能。给定大约6GB的可用内存,我如何配置mysql服务器尽可能多地使用它来计算一个查询?

1 个答案:

答案 0 :(得分:0)

好的,我已经google了一下并进行了实验。我在my.cnf中设置了以下值:

innodb_buffer_pool_size = 768M
sort_buffer_size        = 64M 
key_buffer_size         = 64M
read_buffer_size        = 64M

这使我的查询缩短到20分钟,这对我来说没问题。

一些参考文献: