MYSQL按小数10,10

时间:2015-10-12 15:16:45

标签: mysql

我有大约2500万行,包含0.183463545,0.183423545,0.183443545,0.183443445,0.183447545等。

我需要订购这些,但它目前需要大约20秒。有什么方法可以加快速度吗? AFAIK,我的索引正确放置了。

谢谢!

SELECT `a`.`float_val`,
   `a`.`num_id`,
   `b`.`userID`,
   `c`.`img`,
   `c`.`username`,
   `b`.`img`,
   `d`.`exterior`
FROM `a`
INNER JOIN `b` ON `b`.`num_id` = `a`.`num_id`
INNER JOIN `d` ON `d`.`id` = `b`.`item`
INNER JOIN `c` ON `c`.`userID` = `b`.`userID`
WHERE `float_val` IS NOT NULL
AND `float_val` BETWEEN 0 AND 1
AND `username` = 'ABC'
ORDER BY `float_val` LIMIT 100

索引位于float_valnum_iduserID

CREATE TABLE `float` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`num_id` bigint(11) DEFAULT NULL,
`float_val` decimal(10,10) DEFAULT NULL,
`userID` char(17) DEFAULT NULL,
`last_checked` datetime DEFAULT NULL,
`index10` smallint(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `floatID` (`num_id`),
UNIQUE KEY `num_id` (`num_id`,`userID`),
KEY `userID` (`userID`),
KEY `float_val` (`float_val`),
KEY `last_checked` (`last_checked`),
KEY `index10` (`index10`)
) ENGINE=InnoDB AUTO_INCREMENT=25750916 DEFAULT CHARSET=latin1;

1 个答案:

答案 0 :(得分:0)

已编辑以反映所显示的表格定义。

首先执行查询以获取表float_val中的最低a行。

       SELECT a.id
         FROM a
         INNER JOIN b ON b.num_id = a.num_id
         INNER JOIN d ON d.id = b.item
         INNER JOIN c ON c.userID = b.userID
         WHERE c.username = 'ABC'
           AND a.float_val BETWEEN 0.0 AND 1.0
         ORDER BY a.float_val
        LIMIT 100

如果您在a(float_val,num_id)上有索引,而在c.username上有另一个索引,那么这个索引会相当快。它会为您查询的候选行id吐出a个值。 (如果您正在使用MyISAM,则需要a(float_val, num_id, id)上的索引。顺便说一下,BETWEEN子句也暗示IS NOT NULL。

然后将其用作子查询来完成查询,如下所示。

SELECT a.float_val,
   a.num_id,
   b.userID,
   c.img,
   c.username,
   b.img,
   d.exterior
FROM a
INNER JOIN (
       SELECT a.id
         FROM a
         INNER JOIN b ON b.num_id = a.num_id
         INNER JOIN d ON d.id = b.item
         INNER JOIN c ON c.userID = b.userID
         WHERE c.username = 'ABC'
           AND a.float_val BETWEEN 0.0 AND 1.0
         ORDER BY a.float_val
        LIMIT 100
     ) q ON a.ID = q.id
INNER JOIN b ON b.num_id = a.num_id
INNER JOIN d ON d.id = b.item
INNER JOIN c ON c.userID = b.userID
WHERE c.username = 'ABC'
  AND a.float_val BETWEEN 0.0 AND 1.0
ORDER BY a.float_val  LIMIT 100

这种查询包含延迟连接。这大大减少了需要ORDER BY ... LIMIT的完整查询的行数。如果没有延迟连接,您的原始查询会排出大量相当长的行,只是为了丢弃除前100行之外的所有行。这就是为什么需要这么长时间。

这应该有所帮助。下一个优化步骤是查看此查询的EXPLAIN输出以及表的确切定义。

专业提示:在这种复杂性的查询中,始终使用表名或别名限定列名。也就是说,始终使用a.float_val,而不仅仅是float_val。这是对下一个查看查询的人的好意。