[英]Speeding up a SQL query with generic data information
Due to a variety of design decisions, we have a table, 'CustomerVariable'. 由于各种设计决策,我们有一个表'CustomerVariable'。 CustomerVariable has three bits of information--its own id, an id to Variable (a list of possible settings the customer can have), and the value for that variable.
CustomerVariable有三位信息 - 它自己的id,变量的id(客户可以拥有的可能设置列表),以及该变量的值。 The Variable table, on the other hand, has the information on a default--in case the CustomerVariable is not set.
另一方面,Variable表具有默认信息 - 如果未设置CustomerVariable。
This works well in most situations, allowing us not to have to create an insanely long list of information--especially in a case where there are 16 similar variables that need to be handled for a customer. 这在大多数情况下都很有效,这使我们不必创建一个非常长的信息列表 - 特别是在需要为客户处理16个类似变量的情况下。
The problem comes in trying to get this information into a select. 问题在于尝试将此信息输入选择。 So far, our 'best' solution involves far too many joins to be efficient--we get a list of the 16 VariableIds we need information on, setting them into variables, first.
到目前为止,我们的“最佳”解决方案涉及太多有效的连接 - 我们得到了一个我们需要信息的16个VariableId的列表,首先将它们设置为变量。 Later on, however, we have to do this:
然而,稍后,我们必须这样做:
CROSS JOIN dbo.Variable v01
LEFT JOIN dbo.CustomerVariable cv01 ON cv01.customerId = c.id
AND cv01.variableId = v01.id
CROSS JOIN dbo.Variable v02
LEFT JOIN dbo.CustomerVariable cv02 ON cv02.customerId = c.id
AND cv02.variableId = v02.id
-- snip --
CROSS JOIN dbo.Variable v16
LEFT JOIN dbo.CustomerVariable cv16 ON cv16.customerId = c.id
AND cv16.variableId = v16.id
WHERE
v01.id = @cv01VariableId
v02.id = @cv02VariableId
-- snip --
v16.id = @cv16VariableId
I know there has to be a better way, but we can't seem to find it amidst crunch time. 我知道必须有更好的方法,但我们似乎无法在关键时刻找到它。 Any help would be greatly appreciated.
任何帮助将不胜感激。
If your data set is relatively small and not too volatile, you may want to use materialized views (assuming your database supports them) to optimize the lookup. 如果您的数据集相对较小且不太易变,您可能希望使用物化视图(假设您的数据库支持它们)来优化查找。
If materialized views are not an option, consider writing a stored procedure that retrieves that data in two passes: 如果物化视图不是一个选项,请考虑编写一个存储过程,该过程在两次传递中检索该数据:
Essentially, this is the equivalent of: 从本质上讲,这相当于:
SELECT variableId,
CASE WHEN CV.variableId = NULL THEN VR.defaultValue ELSE CV.value END
FROM Variable VR
LEFT JOIN CUstomerVariable CV on CV.variableId = VR.variableId
WHERE CV.customerId = c.id
The type of query you want is called a pivot table or crosstab query. 您想要的查询类型称为数据透视表或交叉表查询。
By far the easiest way of dealing with this is to create a view based off of a crosstab query. 到目前为止,处理此问题的最简单方法是基于交叉表查询创建视图。 This will flip the columns from being vertical to being horizontal like a regular sql table.
这会将列从垂直翻转为水平,就像常规的sql表一样。 Once that is done, just query the view.
完成后,只需查询视图即可。 Easy.
简单。 ;)
;)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.