mysql - SQL 无限加载
问题描述
我有一个包含 100 万条记录的数据库,使用JOIN、GROUP BY、ORDER进行简单查询的响应时间约为 1.2 秒。没关系,没有问题。我正在努力使用表别名来简化查询,但是当我使用两个或更多表别名执行简单查询时,请求永远不会结束并且 MariaDB 不再响应,我必须手动重新启动服务。
怎么了?
这是它的结构:
CREATE TABLE `values` (
`id` mediumint(11) UNSIGNED NOT NULL,
`date` int(11) NOT NULL DEFAULT '0',
`indexVar` int(11) NOT NULL,
`value` float NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
数据: 示例
工作查询:
SELECT
v.date,
v.value
FROM
`values` AS v
WHERE
v.date > 1548460800 AND v.indexVar = 6 OR v.indexVar = 2
无限加载查询:
SELECT DISTINCT
v.date,
v1.value,
v2.value
FROM
`values` AS v,
`values` AS v1,
`values` AS v2
WHERE
v.date > 1548460800 AND v1.indexVar = 6 AND v2.indexVar = 2
解决方案
您没有在查询中包含任何连接条件。
如果 values 表有 100 万行,那么将其包含两次会给您一个包含 100 万 * 100 万 = 1 万亿行的结果集。你正在应用一些条件,但你仍然会得到大量的结果。(并且您将值表包括了三遍!)
假设你有一个有一百万行的表,每一行只是一个从 1 到 100 万的整数。如果你这样做,select value from values where value > 900000
那么你将获得 100,000 行。但是,如果您说select value from values v, values v2 where v.value > 900000
对于与条件匹配的 100,000 行中的每一行,v.value > 900000
您将从 v2 中获得所有百万行。即使您将相同的过滤器应用于 v2(即v2.value > 900000
),查询仍将为原始值表中的每一行返回 100,000 个 v2 行——总共 100 亿行。
如果date
是表的主键,那么您必须确保date
每个结果行中的所有值都相同:
select v.date, v1.value, v2.value
from values v, values v1, values v2
where v.date = v1.date and v.date = v2.date
and v1.indexVar = 6 and v2.indexVar = 2
或者更好:
select v.date, v1.value, v2.value
from values v
inner join values v1 on (v1.date = v.date)
inner join values v2 on (v2.date = v.date)
where v1.indexVar = 6 and v2.indexVar = 2
如果主键是,id
那么只需对id
. (你说你想根据日期对齐行,所以不确定哪一列最重要。)
推荐阅读
- spring-boot - 如何将 Spring Security OAuth2 与 Apache Wicket 一起使用?
- javascript - 您可以将 html 直接插入 r shiny 中的 navbarPage 吗?
- python - 即使创建了模块,也找不到 Python 模块
- watchkit - XCode 12.5 无法部署到配对手表的手机 - 设备“(null)”未在您的开发者帐户中注册
- python - 从烧瓶请求中获取模型数据
- vue.js - 按钮元素加加载
- ruby - 是否可以简化此方法?
- node.js - Sequelize onDelete CASCADE 不起作用
- javascript - 使用多维数组构建对象以动态创建列
- php - Google Adwords API:INVALID_TOKEN_HEADER 使用新 API 和正确的开发者令牌时(我相信)