我有一张桌子,里面有大约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上分区表...我不确定如果它适用于子分区...
答案 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。