*大家好,我正在进行查询,并且不确定如何尽可能快地进行查询并尽可能减少冗余。我真的希望那里有人可以帮我提出一个很好的方法。
提前感谢您的帮助!*
好的,所以这就是我最好的解释。我简化了表格和数学,以便了解我想要了解的内容。
基本上我有一个永远不会改变的小表,并且总是只有这样的50k记录:
Values_Table
ID Value1 Value2
1 2 7
2 2 7.2
3 3 7.5
4 33 10
….50000 44 17.2
并且有几张表不断变化并且相当大,例如可能有多达500万条记录:
Flags_Table
Index Flag1 Type
1 0 0
2 0 1
3 1 0
4 1 1
….5,000,000 1 1
Users_Table
Index Name ASSOCIATED_ID
1 John 1
2 John 1
3 Paul 3
4 Paul 3
….5,000,000 Richard 2
我需要将所有3张桌子绑在一起。从小表中可能返回的最多结果是在100个结果附近。大型表在索引上连接,然后将这些表连接到Values_Table ON Values_Table.ID = Users_Table.ASSOCIATED_ID ....那部分很容易。
对我来说棘手的是我需要尽快返回一个限制为10个结果的列表,其中value1和value2以数学方式操作以返回new_值,其中new_value小于10且结果按new_value排序,我需要的任何其他语句都可以应用于标志。我确实需要能够沿着极限移动。 EG LIMIT 0,10 / 11,10 / 21,10等......
在后续(或相同的可能)查询中,我需要在应用限制之前获得与该条件匹配的所有类型的前10个计数。
所以例如我想加入所有这些并返回Value1 + Value2< 10我还需要点数。
所以我想要的是:
Index Name Flag1 New_Value
1 John 0 9
2 John 0 9
5000000 Richard 1 9.2
第二个回应是:
ID (not index) Count
1 2
2 1
我尝试了几种方法,最终提出了以下有点难看的问题:
SELECT INDEX, NAME, Flag1, (Value1 * some_variable + Value2) as New_Value
FROM Values_Table
JOIN Users_Table ON ASSOCIATED_ID = ID
JOIN Flags_Table ON Flags_Table.Index = Users_Table.Index
WHERE (Value1 * some_variable + Value1) < 10
ORDER BY New_Value
LIMIT 0,10
然后计算:
SELECT ID, COUNT(TYPE) as Count, (Value1 * some_variable + Value2) as New_Value
FROM Values_Table
JOIN Users_Table ON ASSOCIATED_ID = ID
JOIN Flags_Table ON Flags_Table.Index = Users_Table.Index
WHERE (Value1 * some_variable + Value1) < 10
GROUP BY TYPE
ORDER BY New_Value
LIMIT 0,10
能够在我的WHERE子句中过滤不同的标志是很重要的;这可能听起来很愚蠢,但我提到,因为我可以看到一个更快的方法是使用HAVING语句,但我不相信这将在某些情况下工作取决于我想要使用我的WHERE子句过滤。
使用标记表进行过滤时:
SELECT INDEX, NAME, Flag1, (Value1 * some_variable + Value2) as New_Value
FROM Values_Table
JOIN Users_Table ON ASSOCIATED_ID = ID
JOIN Flags_Table ON Flags_Table.Index = Users_Table.Index
WHERE (Value1 * some_variable + Value1) < 10 AND Flag1 = 0
ORDER BY New_Value
LIMIT 0,10
...过滤计数:
SELECT ID, COUNT(TYPE) as Count, (Value1 * some_variable + Value2) as New_Value
FROM Values_Table
JOIN Users_Table ON ASSOCIATED_ID = ID
JOIN Flags_Table ON Flags_Table.Index = Users_Table.Index
WHERE (Value1 * some_variable + Value1) < 10 AND Flag1 = 0
GROUP BY TYPE
ORDER BY New_Value
LIMIT 0,10
工作正常但必须为每一行多次运行数学运算,我感到唠叨的感觉是它还在Values_table表的同一行上多次运行数学运算。我的想法是,我应该首先只获取Values_table的有效响应,然后将这些响应连接到其他表以减少处理; SQL如何优化,但我不确定它是否可能已经这样做了。我知道我可以使用HAVING子句只运行数学一次,如果我这样做,但我不确定我最好如何加入。
我的问题是:
看起来这应该很简单,但我只是错过了一些愚蠢的东西。
我打算进入一个临时表,然后将该表连接到自身,但这似乎我会交换数学表针对表进行迭代,但结果仍然很慢。
感谢大家的帮助,如果我需要澄清一下,请告诉我!
**为了澄清一个问题,我不能使用预先计算出的值的第3列,因为实际上数学比添加要复杂得多,我只是为了说明而简化它。
答案 0 :(得分:1)
您是否有基准查询进行比较?通常,尝试超越优化器并不起作用。如果您从一个起始查询中获得了可接受的性能,那么您可以看到正在花费额外工作的位置(由磁盘读取,缓存消耗等指示)并专注于此。
避免诱惑将其分解成碎片并解决它们。这是一个反模式。这尤其包括临时表。
冗余数学通常没问题 - 磁盘活动会带来什么伤害。我从未见过在纯计算中需要减少CPU工作量的查询。
答案 1 :(得分:0)
收集结果并将其放入临时表
SELECT * into TempTable FROM (SELECT INDEX, NAME, Type, ID, Flag1, (Value1 + Value2) as New_Value
FROM Values_Table
JOIN Users_Table ON ASSOCIATED_ID = ID
JOIN Flags_Table ON Flags_Table.Index = Users_Table.Index
WHERE New_Value < 10)
ORDER BY New_Value
LIMIT 0,10
首次查询的返回结果
SELECT INDEX, NAME, Flag1, New_Value
FROM TempTable
返回类型计数的结果
Select ID, Count(Type)
FROM TempTable
GROUP BY TYPE
答案 2 :(得分:0)
您是否有可能使用预先计算的值将第三列添加到values_table?即使计算结果依赖于其他变量,也可以运行整个表的计算,但只有当这些变量发生变化时才会运行。