我有一张这样的 table
CREATE TABLE IF NOT EXISTS `billing_success` (
`bill_id` int(11) NOT NULL AUTO_INCREMENT,
`msisdn` char(10) NOT NULL,
`circle` varchar(2) NOT NULL,
`amount` int(11) NOT NULL,
`reference_id` varchar(100) NOT NULL,
`source` varchar(100) NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`bill_id`),
KEY `msisdn` (`msisdn`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=8573316 ;
并且我想添加复合索引来优化查询。这是我生成报告的表格,最近它变得非常慢。这些是我生成报告的查询
1.SELECT msisdn,amount,circle FROM billing_total_success WHERE (source='XX' OR source='Y' OR source='STR') AND (time like '$date%')
2.SELECT msisdn,amount,circle FROM billing_total_success WHERE source <> 'RNH' AND source <> 'STR' AND source <> 'XAS' AND source <> 'RTR' AND (time like '$date%')
3.SELECT msisdn,amount,circle FROM billing_total_success WHERE (source='STR' OR source='RER' OR source='ASD') AND time BETWEEN '$date1' AND '$date2'
4.SELECT msisdn,amount,circle FROM billing_total_success WHERE (source='RNH') AND time BETWEEN '$date1' AND '$date2'
请告诉我应该在哪里为这些要优化的查询添加索引,以及如何在给定的查询中添加适当的索引。
最佳答案
一个。您可能需要时间戳字段上的索引。
然而,这不一定是故事的结局;如果您的查询是对时间戳索引进行范围扫描,那么在 InnoDB 中将其作为二级索引不一定是个好主意。
B.使时间戳成为主键的第一部分
这是违反直觉的,但是由于 InnoDB 集群在主键上,将时间戳放在主键的第一部分将使二级索引范围扫描变成主键范围扫描,这通常更好。二级索引范围扫描需要检索范围内的每一行;主键扫描已经检索到了它。
C.按时间划分
如果您的查询速度很慢,因为表变得对内存来说太大了(经常需要 IO 读取),但您总是查询一个小的(大概)时间范围,请考虑按天或按小时进行分区。
当然,如果您的用户位于不同时区,则每日分区的效果会差很多,因为他们的日子与分区的日子重叠。
分区需要脚本对表进行持续维护(创建新分区;删除旧分区)。您需要提供并测试这些脚本,因此这显然是开发人员的开销。运营也需要监控这些脚本,因此它们也有运营开销。
关于mysql - MYSQL表添加复合索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5762813/