哪些索引应该有一个表来快速执行大型SQL查询?

时间:2013-10-10 20:08:33

标签: mysql sql indexing

我有一张表,数据很快就会传播。这是它的结构:

CREATE TABLE `tasks_pending` (
  `pending_id` int(11) NOT NULL AUTO_INCREMENT,
  `task_id` int(9) NOT NULL,
  `user_id` int(9) NOT NULL,
  `added_time` int(11) NOT NULL DEFAULT '0',
  `additional` varchar(1000) DEFAULT NULL,
  `taken` tinyint(1) NOT NULL DEFAULT '0',
  `taken_by` int(11) NOT NULL,
  `taken_time` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`pending_id`),
  UNIQUE KEY `task_id` (`task_id`,`user_id`),
  KEY `user_id` (`user_id`),
  KEY `added_time` (`added_time`),
  KEY `task_id_2` (`task_id`),
  KEY `taken` (`taken`)
) ENGINE=MEMORY

此外,我还有一个可以提取所需数据的大查询:

SELECT DISTINCT `task_id` AS tid, `pending_id` as pid, `taken_time`, `taken_by`,  `additional`, 
(
    SELECT COUNT( pending_id ) 
    FROM tasks_pending tp
    WHERE task_id = tid
) AS count, 
(
    SELECT remain
    FROM tasks
    WHERE task_id = tid
) AS rem, 
(
    SELECT type 
    FROM tasks tas
    WHERE task_id = tid
) AS type 
FROM  `tasks_pending` 
WHERE  `taken` =  '0'
HAVING 
(
    count > 9
    OR count = rem
    OR type =  'pack'
)
limit 30

子查询的where子句中的所有列都具有PRIMARY索引,因此它们必须快速执行。 我找不到问题,也许你可以吗?提前谢谢。

P.S。我是俄罗斯人,很抱歉英语不好。

UPD:tasks表的结构:

CREATE TABLE `tasks` (
  `task_id` int(50) NOT NULL AUTO_INCREMENT,
  `user_id` int(50) DEFAULT NULL,
  `type` enum('video','friend','group','like','pack','other') NOT NULL,
  `url` varchar(500) NOT NULL,
  `additional` varchar(1000) DEFAULT NULL,
  `remain` int(30) DEFAULT NULL,
  `created_at` int(11) NOT NULL DEFAULT '0',
  `updated_at` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`task_id`),
  KEY `user_id` (`user_id`),
  KEY `remain` (`remain`),
  KEY `created_at` (`created_at`),
  KEY `updated_at` (`updated_at`)
) ENGINE=InnoDB 

1 个答案:

答案 0 :(得分:1)

您可以尝试使用GROUP BY子句并删除子选择来简化查询。这可以提高性能。试试这个:

SELECT  t.task_id, COUNT(pending_id) count, taken_time, taken_by, type, remain

FROM    tasks_pending tp

        JOIN tasks t ON tp.task_id = t.tid

WHERE   taken = 0

GROUP BY task_id

HAVING  count > 9
        OR count = remain
        OR type =  'pack'

limit 30