【问题标题】:MySQL optimization - 7.5m rowsMySQL 优化 - 750 万行
【发布时间】:2014-12-27 11:14:43
【问题描述】:

我在 MySQL 中有一个包含 7 500 000 行的表,但查询持续时间有问题。任何人都可以帮助我提供一些提示以使其更快吗? 表称为“出勤”。它在 col move_date、employee_id 上有索引,我尝试在两个 cols 上创建索引。但是下面的查询大约需要 9 秒,对我来说太慢了。有没有人一些提示?我需要使用超过 14 个员工 ID 进行此选择。

SELECT * 
FROM attendance 
WHERE movement_date >= '2014-09-01 00:00:00' 
AND movement_date <= '2014-10-01 23:59:59' 
AND employee_id IN (14 integer ids...);

表定义:

CREATE TABLE `attendance` (
  `attendance_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `attendance_raw_id` int(10) unsigned DEFAULT NULL,
  `employee_id` int(11) NOT NULL,
  `shift_type_id` int(11) DEFAULT NULL,
  `shift_plan_id` int(11) DEFAULT NULL,
  `record_status_id` tinyint(4) DEFAULT ''1'',
  `movement_date` datetime DEFAULT NULL,
  `attendance_movement_type_id` tinyint(4) DEFAULT NULL,
  `note` varchar(50) DEFAULT NULL,
  `created_d` datetime DEFAULT NULL,
  `created_w` int(11) DEFAULT NULL,
  `updated_w` int(11) DEFAULT NULL,
  PRIMARY KEY (`attendance_id`),
  UNIQUE KEY `IDX_attendance_raw_id` (`attendance_raw_id`),
  KEY `IDX_employee_id` (`employee_id`),
  KEY `FK_attendance3` (`attendance_movement_type_id`),
  KEY `IDX_movement_date` (`movement_date`),
  KEY `FK_attendance4` (`record_status_id`),
  KEY `FK_movement_date_employee` (`movement_date`,`employee_id`),
  CONSTRAINT `FK_attendance` FOREIGN KEY (`employee_id`) REFERENCES `employee` (`employee_id`),
  CONSTRAINT `FK_attendance2` FOREIGN KEY (`attendance_raw_id`) REFERENCES `attendance_raw` (`attendance_raw_id`),
  CONSTRAINT `FK_attendance3` FOREIGN KEY (`attendance_movement_type_id`) REFERENCES `attendance_movement_type` (`attendance_movement_type_id`),
  CONSTRAINT `FK_attendance4` FOREIGN KEY (`record_status_id`) REFERENCES `record_status` (`record_status_id`)
) ENGINE=InnoDB AUTO_INCREMENT=9072724 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC

【问题讨论】:

  • 使用explain 查看您需要索引的位置。
  • 将表定义添加到问题show create table attendance会给你完整的定义。
  • 是的,看起来您有一个复合索引 FK_movement_date_employee,应该考虑在内。你能不能把索引IDX_employee_id删掉,然后试试看你得到了什么。

标签: mysql select optimization large-data


【解决方案1】:

为了提高结果的速度,你需要这样改变你的sql语句

SELECT * 
FROM attendance 
WHERE movement_date >= '2014-09-01 00:00:00' 
AND movement_date <= '2014-10-01 23:59:59' 
AND employee_id IN(
                   SELECT  indexed_column_IDs
                   FROM    table2 ...
                   )

从一定数量的记录开始,SELECT 上的 IN 谓词变得比常量列表上的更快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-02
    • 2018-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-14
    • 2012-05-16
    相关资源
    最近更新 更多