2017-07-18 83 views
0

我有一个用于存储统计信息的表格。目前,在一天结束时会填充约1,000万行,然后复制到每日统计信息表并删除。由于这个原因,我不能有一个自动递增的主键。这个数据库表的最佳索引是什么?

这是表结构:

CREATE TABLE `stats` (
`shop_id` int(11) NOT NULL, 
`title` varchar(255) CHARACTER SET latin1 NOT NULL, 
`created` datetime NOT NULL, 
`mobile` tinyint(1) NOT NULL DEFAULT '0', 
`click` tinyint(1) NOT NULL DEFAULT '0', 
`conversion` tinyint(1) NOT NULL DEFAULT '0', 
`ip` varchar(20) CHARACTER SET latin1 NOT NULL, 
KEY `shop_id` (`shop_id`,`created`,`ip`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

我有shop_id, created, ip的关键,但我不知道我应该使用哪些列创建最优指标,以增加查找速度进一步?

下面的查询需要,无钥匙约12秒,约1.5秒使用指数之上:

SELECT DATE(CONVERT_TZ(`created`, 'UTC', 'Australia/Brisbane')) AS `date`, COUNT(*) AS `views` 
FROM `stats` 
WHERE `created` <= '2017-07-18 09:59:59' 
AND `shop_id` = '17515021' 
AND `click` != 1 
AND `conversion` != 1 
GROUP BY DATE(CONVERT_TZ(`created`, 'UTC', 'Australia/Brisbane')) 
ORDER BY DATE(CONVERT_TZ(`created`, 'UTC', 'Australia/Brisbane')); 
+0

您已经创建了shop_id,然后在您的where子句中单击......等等。 按相同的顺序创建索引。 – money

+0

KEY created_shopid_click_conversion(created,shop_id,click,conversion); – money

回答

1
  • 如果没有列(或列的组合),其保证唯一的,然后做具有AUTO_INCREMENT id。不要担心截断/删除。 (但是,如果该ID未重置,则可能需要使用BIGINT而不是INT UNSIGNED以避免溢出。)
  • 请勿使用id作为主键,而应使用PRIMARY KEY(shop_id, created, id), INDEX(id)
  • 这种非传统的PK将有助于两种方式的表现,同时又是唯一的(由于增加了id)。 INDEX(id)是保持AUTO_INCREMENT高兴。 (无论您每小时还是每天都需要DELETE是一个单独问题。)
  • 根据每小时(或每分钟)生成一个摘要表。它将包含如此的计数 - 400K /小时或7K /分钟。每小时(或每分钟)增加一次,以便在一天结束时不必完成所有工作。
  • 汇总表还可以对点击和/或转换进行过滤。 它可以保持两个,如果你需要它们。
  • 如果点击/转换只有两个状态(0 & 1),请不要说!= 1,比如= 0;优化器在=比在!=好得多。
  • 如果他们2态,你改变为=,那么这变得可行和好得多:INDEX(shop_id, click, conversion, created) - created必须是最后一个。
  • 汇总到汇总表时,不要打扰TZ;稍后再应用转换。
  • 更好的是,不要使用DATETIME,使用TIMESTAMP,这样你就不需要转换(假设你已经正确设置了TZ)。

毕竟,如果你仍然有问题,重新开始问题;可能会有进一步的调整。

-1

在你的where子句中,使用列第一,这将返回小结果集等并以相同的顺序创建索引。
你有
WHERE created <= '2017-07-18 09:59:59' AND shop_id = '17515021' AND click != 1 AND conversion != 1

如果创建将返回少数集作为比较其他3列,那么你在第一个位置不错的,否则你该列的where子句,然后选择第二列按相同解释并根据您的where子句创建索引。
如果您认为订单没有问题,请创建索引

KEY created_shopid_click_conversion (created,shop_id, click, conversion);

+0

'WHERE'中的顺序确实无关紧要。 'KEY'中的顺序_问题。并且范围('created')不应该(极少数例外)在索引中首先出现。 –

相关问题