简体   繁体   English

使用通用数据信息加速SQL查询

[英]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: 如果物化视图不是一个选项,请考虑编写一个存储过程,该过程在两次传递中检索该数据:

  1. First retrieve all of the CustomerVariables available for a particular customer (or set of customers) 首先检索特定客户(或客户组)可用的所有CustomerVariables
  2. Next, retrieve all of the default values from the Variables table 接下来,从Variables表中检索所有默认值
  3. Perform a non-distinct union on the results merging the defaults in wherever a CustomerVariable record is missing. 在缺少CustomerVariable记录的任何地方合并默认值的结果上执行非独特的并集。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM