MySQL - 关于表分区/子分区的说明

时间:2015-09-13 22:34:55

标签: mysql database innodb database-partitioning

我有一张桌子,里面有大约3亿条记录(仅限60天)。表结构很简单..
它有12列,其中4列是索引的:

LogTime - DateTime
RegionID - Integer
ProvinceID - Integer
CityID - Integer

还有一个独特的指数:

UNIQUE INDEX UI_IDX (`LogTime`, `RegionID`, `ProvinceID`, `CityID`); 

其余字段只是主要由查询结果提取的值。

数据库服务器已经调整好了条件(缓冲区空间大约等于12GB)

好吧,为了加快查询速度,我决定在LogTime字段上对表进行分区。我通过使用PARTITION BY RANGE对表进行分区来实现此目标。现在我有365个分区表(1个分区1天,每个分区5百万个记录)。

问题是我们对查询性能不满意,我正在寻找一种方法将分区分解为更小的部分..让我们说在LogTime和RegionID上分区表...我不确定如果它适用于子分区...

1 个答案:

答案 0 :(得分:0)

有关

select  b.CityName, a.val1, a.val2
    from  DataRepo a
    left join  City b on a.CityID = b.CityID
    where  (a.LogTime >= '2015-08-01 00:00:00'
       and  a.LogTime <= '2015-08-05 00:00:00' )
      and  a.RegionID = 1
      and  a.ProvinceID = 14;

最佳指数是

INDEX(RegionID, ProvinceID, -- in either order
      LogTime)    -- last

PARTITIONing将有助于将查询加速到该索引可以提供的内容之上。

(无关) 你有意想检查4天加1秒吗?

我喜欢这种设计模式:

    where  (a.LogTime >= '2015-08-01'
       and  a.LogTime <  '2015-08-01' + INTERVAL 4 DAY )

哦......这个指数会更快,因为它是&#34;覆盖&#34;:

INDEX(RegionID, ProvinceID, -- in either order
      LogTime,    -- range
      CityID)     -- the rest of the fields used in the SELECT

这样,查询将完全执行(除了JOIN)索引,而不会触及数据。 EXPLAIN会说&#34;使用索引&#34;。

(另外一边)区域是省的一部分吗?或相反亦然?如果是这样,你不需要事实表中的两列,对吗? (收缩事实表是另一种提高性能的技术,因为你无疑是I / O绑定的。)

(更多)省INT?这是4个字节。如果有不到255个省,请使用TINYINT UNSIGNED,这只是1个字节。这将在表格中节省近1GB,再加上我提议的索引中的另一个GB。