【问题标题】:WHERE vs HAVING in generated queries生成的查询中的 WHERE 与 HAVING
【发布时间】:2013-07-30 14:04:25
【问题描述】:

我知道这个标题被过度使用了,但我的问题似乎还没有得到回答。 所以,问题是这样的:

我有一个由四个表(表、行、列、值)组成的表结构,我用它们来重新创建 information_schema 的行为(以某种方式)。 在 php 中,我正在生成查询来检索数据,结果仍然看起来像一个普通的表:

SELECT 
  (SELECT value FROM `values` WHERE `col` = "3" and row = rows.id) as "col1",
  (SELECT value FROM `values` WHERE `col` = "4" and row = rows.id) as "col2" 
FROM rows WHERE `table` = (SELECT id FROM tables WHERE name = 'table1') 
HAVING (col2 LIKE "%4%")

SELECT * FROM 
(SELECT 
  (SELECT value FROM `values` WHERE `col` = "3" and row = rows.id) as "col1",
  (SELECT value FROM `values` WHERE `col` = "4" and row = rows.id) as "col2" 
FROM rows WHERE `table` = (SELECT id FROM tables WHERE name = 'table1')) d 
WHERE col2 LIKE "%4%" 

请注意,我定义结果列的部分是由 php 脚本生成的。我为什么这样做并不重要,但我想扩展这个生成查询以供更广泛使用的算法。 我们解决了核心问题,我必须决定是否为查询生成wherehaving 部分,并且我知道何时同时使用它们,问题是我的算法没有,我有为此做一些额外的检查。但是上面的两个查询是等价的,我总是可以将任何查询放在一个子查询中,给它一个别名,并在新的派生表上使用 where。但我想知道我的性能是否会出现问题,或者这是否会以一种意想不到的方式反过来影响我。

我知道它们是如何工作的,以及应该如何更快,但这就是我来这里询问的原因。希望我能理解自己,请原谅我的英语和冗长无用的短语,等等。

编辑 1

我已经知道两者之间的区别,这意味着,我唯一的困境是使用来自其他表的自定义列,具有可变的数字和大小,并尝试获得与使用正常创建的表相同的结果意味着我必须使用 HAVING 过滤派生表列,同时可以选择将其包装在子查询中并正常使用 where,这可能会创建一个临时表,之后将被过滤。这会影响大型数据库的性能吗?不幸的是,我现在无法对此进行测试,因为我负担不起用超过 10 亿个条目填充数据库(这将是这样的:rows 表中有 10 亿个,values 表中有 50 亿个,每行cols 表中有 5 列 5 行,tables 表中有 1 行 = 6,000,006 个条目)

现在我的数据库是这样的:

+----+--------+-----------+------+
| id | name   | title     | dets |
+----+--------+-----------+------+
|  1 | table1 | Table One |      |
+----+--------+-----------+------+

+----+-------+------+
| id | table | name |
+----+-------+------+
|  3 |     1 | col1 |
|  4 |     1 | col2 |
+----+-------+------+
where `table` is a foreign key from table `tables` 


+----+-------+-------+
| id | table | extra |
+----+-------+-------+
|  1 |     1 |       |
|  2 |     1 |       |
+----+-------+-------+
where `table` is a foreign key from table `tables` 

+----+-----+-----+----------+
| id | row | col | value    |
+----+-----+-----+----------+
|  1 |   1 |   3 | 13       |
|  2 |   1 |   4 | 14       |
|  6 |   2 |   4 | 24       |
|  9 |   2 |   3 | asdfghjk |
+----+-----+-----+----------+
where `row` is a foreign key from table `rows` 
where `col` is a foreign key from table `cols` 

编辑 2

条件仅用于演示目的!

编辑 3

只有两行,两者之间似乎存在差异,使用have的是0,0008,使用where的是0.0014-0.0019。我想知道这是否会影响大量行和列的性能

编辑 4

两次查询的结果是一样的,即:

+----------+------+
| col1     | col2 |
+----------+------+
| 13       | 14   |
| asdfghjk | 24   |
+----------+------+

【问题讨论】:

    标签: php mysql sql


    【解决方案1】:

    HAVING是专门为GROUP BYWHERE是提供条件参数。另见WHERE vs HAVING

    【讨论】:

    • 是的,我已经看过了,我有一个不同的问题,请阅读编辑。
    • 链接的问题深入探讨:HAVING 应用在 WHERE 之后,并且 HAVING 能够对聚合结果进行操作。
    • 嗯,这几乎概括了我的问题的答案,我想我必须进行一些预计算以确定系统应该如何构建查询。谢谢。
    【解决方案2】:

    我相信在这种情况下,having 子句会更快,因为您要定义特定的值,而不是通读值并寻找匹配项。

    【讨论】:

    • 但是当我生成整个查询时,我希望能够根据我的别名放置特定的过滤条件,就好像我会使用“真实”表,而不是派生表一样,这是为什么我将它全部包装到一个子查询中。现在,只有两行,两者之间似乎存在差异,使用having 的行是0,0008,使用where 的行是0.0014-0.0019。我想知道这是否会影响大量行和列的性能。
    【解决方案3】:

    见:http://database-programmer.blogspot.com/2008/04/group-by-having-sum-avg-and-count.html

    基本上,WHERE 在将列传递给聚合函数之前过滤掉它们,但 HAVING 过滤聚合函数的结果。

    【讨论】:

    • 是的,但是会创建一个派生表,该表将在包装版本中由我的 where 条件过滤,并且与 having 相同的结果也是因为,毕竟所有行将获得将应用过滤器。我在问为什么会有性能差异,以及它是否会增加。
    【解决方案4】:

    你可以这样做

        WHERE col2 In (14,24)
    

    您的代码 WHERE col2 LIKE "%4%" 是个坏主意,那么 col2 = 34 也会被选中。

    【讨论】:

    • 这是一个虚拟条件,它只是作为演示。
    • @khael 和我的情况需要多少钱?
    • 不幸的是,我认为您错过了一点,您看我对使用where -VS- 使用having 的子查询的包装更感兴趣。无论如何,这是一个虚拟的条件。我的意思是它只是用于测试,实际上它不会被使用。
    猜你喜欢
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 2015-12-14
    相关资源
    最近更新 更多