MYSQL按十进制10,10排序大型数据库

标签 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;

最佳答案

编辑以反射(reflect)显示的表定义。

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

       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 上有另一个索引,那么速度会相当快。它会吐出作为查询候选的 a 行的 id 值。 (如果您使用 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的行数。如果没有延迟连接,您的原始查询会对一大堆相当长的行进行排序,只是为了丢弃除前一百条之外的所有行。这就是为什么需要这么长时间。

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

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

关于MYSQL按十进制10,10排序大型数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33084587/

相关文章:

javascript - 双击更新传单 map 上的位置标记

java - Hibernate 可以使用 MySQL 的 "ON DUPLICATE KEY UPDATE"语法吗?

mysql - 如何将 JSON 数据添加或合并到现有 MySQL 行的 JSON 字段中?

php - 使用 Yii2 将大型数据集导入 MySQL

mysql - mysql如何将表从一个数据库复制到另一个数据库

MySql 查询中的 PHP 变量

php - 根据选定的数据库条目显示数据库中的数据

更新前的 MySQL 使用 PhpMyAdmin 触发插入语法错误

php - 制作喜欢/不喜欢 AJAX 脚本 - 不起作用

python - 是否可以在 python 中重置 sqlalchemy 查询对象的 group_by 项?