- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我最近在 SO 上看到一个请求,将同一 history
表中的三个查询合并为一个以提高性能。
这三个查询是
SELECT COUNT(*) as number, SUM(order_total) as sum FROM history;
SELECT COUNT(*) as number, SUM(order_total) as sum FROM history
WHERE date <= UNIX_TIMESTAMP(DATE_ADD(CURDATE(),INTERVAL -30 DAY));
SELECT COUNT(*) as number, SUM(order_total) as sum FROM history
WHERE date <= UNIX_TIMESTAMP(CURDATE());
所以我想我应该格式化一个更一般的问题,以上面的示例为例:如何组合更多查询,以及如何最好地进行?
最佳答案
所有查询都访问相同的变量,仅用于运行总和和总计的条件有所不同。
要在单个查询中运行这一切,我们必须将每个结果分配给不同的列,因此而不是 number
和sum
我们将有number1
, number2
, ... sum3
,以便访问结果。
一般来说,COUNT()
, SUM()
等是aggregate functions ,因此我们将用包含条件的新表达式替换每个实例。
例如:COUNT(*) WHERE some_condition
与
add 1 for each record among the records where <some_condition>
可以重写(尽管慢一点)为
add 1 if <some_condition>, else 0, for each record among ALL the records
这是
SUM(IF(<some_condition>, 1, 0))
这同样适用于 SUM(value) WHERE <some_condition>
:变成SUM(IF(<some_condition>, value, 0))
.
当考虑MIN()
时, MAX()
和AVG()
,我们看到默认值 0 可能会出现问题。通过使用 NULL 而不是 0 可以解决此问题。
我们的第一次迭代允许简单的替换:
Single query Combined query
COUNT(*) SUM(<conditionalOne>)
SUM(value) SUM(<conditionalValue>)
AVG(value) AVG(<conditionalValue>)
MIN(value) MIN(<conditionalValue>)
...
哪里<conditionalValue>
是,如果 <condition>
存在,
IF(<condition>, value, NULL)
或者简单地value
。 <conditionalOne>
是 <conditionalValue>
其中值等于 1。否则,value
可以是字段名称或表达式。
因此我们的示例查询变为:
SELECT
SUM(1) AS number1, SUM(order_total) AS sum1,
SUM(IF(date <= UNIX_TIMESTAMP(DATE_ADD(CURDATE(),INTERVAL -30 DAY)), 1, NULL)) AS number2,
SUM(IF(date <= UNIX_TIMESTAMP(DATE_ADD(CURDATE(),INTERVAL -30 DAY)), order_total, NULL)) AS sum2,
SUM(IF(date <= UNIX_TIMESTAMP(CURDATE()), 1, NULL)) AS number3,
SUM(IF(date <= UNIX_TIMESTAMP(CURDATE()), order_total, NULL)) AS sum3
FROM history;
在这种情况下,至少有一个条件对整个表有效,即一个查询没有 WHERE
;所以我们需要扫描整个表。那么我们也可以不使用 WHERE
总共。
否则,我们将合并这三个条件并使用其中最大或最宽松的条件(因此,如果我们选择去年、上个月和上周,我们实际上只会添加去年的选择)。
我们可以自动执行此操作,并希望 MySQL 优化器能够解决问题:
WHERE (<condition1>) OR (<condition2>) OR (<condition3>);
由于索引的原因,单个查询实际上运行的速度很可能比多个不连贯的查询慢。如果条件和值实际上针对多个不同的列,则经常会发生这种情况,从而降低索引效率。
如果根本没有索引,那么合并查询应该总是比单独运行它们更方便。
理论上我们希望有一个 covering index包含 WHERE
中出现的所有列子句,从基数最小的到基数最大的,后跟表达式中出现的所有列。这样,MySQL 选择器将快速将所需行归零,并且还将找到内存中已存在的所需值。
在此示例中,条件基于 date
查询要求 order_total
,因此我们将仅使用两列创建索引。
CREATE INDEX history_stat_ndx ON history(`date`, order_total);
但在实践中,覆盖索引很可能太大而无法被接受,或者如果是的话,也没有什么好处。在这种情况下,我们仍然会合并多个查询,但这次合并为多个查询:
需要全表扫描和/或大量列的查询,特别是如果其他查询不需要相同的查询,它将自行进行,并将与具有相同特征的所有其他查询合并,并且不被索引(我们从索引中获得的 yield 很少。对于 WHERE 来说没有好处,因为存在全表扫描,对于覆盖范围来说则没有好处,因为列太多)。
表达式中需要相似条件或相似列集的所有查询都可以分组在一起,如果条件确实相似,则可能会建立索引。每个组可能有自己不同的索引,并针对该组及其表达式进行了优化。
关于mysql - 组合来自同一个表的统计查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32660423/
我有三张 table 。表 A 有选项名称(即颜色、尺寸)。表 B 有选项值名称(即蓝色、红色、黑色等)。表C通过将选项名称id和选项名称值id放在一起来建立关系。 我的查询需要显示值和选项的名称,而
在mysql中,如何计算一行中的非空单元格?我只想计算某些列之间的单元格,比如第 3-10 列之间的单元格。不是所有的列...同样,仅在该行中。 最佳答案 如果你想这样做,只能在 sql 中使用名称而
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 7 年前。 Improve this ques
我正在为版本7.6进行Elasticsearch查询 我的查询是这样的: { "query": { "bool": { "should": [ {
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 7 年前。 Improve this ques
是否可以编写一个查询来检查任一子查询(而不是一个子查询)是否正确? SELECT * FROM employees e WHERE NOT EXISTS (
我找到了很多关于我的问题的答案,但问题没有解决 我有表格,有数据,例如: Data 1 Data 2 Data 3
以下查询返回错误: 查询: SELECT Id, FirstName, LastName, OwnerId, PersonEmail FROM Account WHERE lower(PersonEm
以下查询返回错误: 查询: SELECT Id, FirstName, LastName, OwnerId, PersonEmail FROM Account WHERE lower(PersonEm
我从 EditText 中获取了 String 值。以及提交查询的按钮。 String sql=editQuery.getText().toString();// SELECT * FROM empl
我有一个或多或少有效的查询(关于结果),但处理大约需要 45 秒。这对于在 GUI 中呈现数据来说肯定太长了。 所以我的需求是找到一个更快/更高效的查询(几毫秒左右会很好)我的数据表大约有 3000
这是我第一次使用 Stack Overflow,所以我希望我以正确的方式提出这个问题。 我有 2 个 SQL 查询,我正在尝试比较和识别缺失值,尽管我无法将 NULL 字段添加到第二个查询中以识别缺失
什么是动态 SQL 查询?何时需要使用动态 SQL 查询?我使用的是 SQL Server 2005。 最佳答案 这里有几篇文章: Introduction to Dynamic SQL Dynami
include "mysql.php"; $query= "SELECT ID,name,displayname,established,summary,searchlink,im
我有一个查询要“转换”为 mysql。这是查询: select top 5 * from (select id, firstName, lastName, sum(fileSize) as To
通过我的研究,我发现至少从 EF 4.1 开始,EF 查询上的 .ToString() 方法将返回要运行的 SQL。事实上,这对我来说非常有用,使用 Entity Framework 5 和 6。 但
我在构造查询来执行以下操作时遇到问题: 按activity_type_id过滤联系人,仅显示最近事件具有所需activity_type_id或为NULL(无事件)的联系人 表格结构如下: 一个联系人可
如何让我输入数据库的信息在输入数据 5 分钟后自行更新? 假设我有一张 table : +--+--+-----+ |id|ip|count| +--+--+-----+ |
我正在尝试搜索正好是 4 位数字的 ID,我知道我需要使用 LENGTH() 字符串函数,但找不到如何使用它的示例。我正在尝试以下(和其他变体)但它们不起作用。 SELECT max(car_id)
我有一个在 mysql 上运行良好的 sql 查询(查询 + 连接): select sum(pa.price) from user u , purchase pu , pack pa where (
我是一名优秀的程序员,十分优秀!