Sql 能够(但在有多个dim值的情况下有多行)。这个过程称为数据库规范化。然后,您将能够使用单个选择执行查询,而无需将一组选择组合在一起

Sql 能够(但在有多个dim值的情况下有多行)。这个过程称为数据库规范化。然后,您将能够使用单个选择执行查询,而无需将一组选择组合在一起,sql,performance,tsql,Sql,Performance,Tsql,对于编写的查询(这适用于具有更正的数据库结构的改进查询),您需要确定是否使用索引来解决查询。在您的情况下,最佳索引将是(客户机,时段)或(时段,客户机)之一,具体取决于这些索引的基数(基本上,这些列中存在多少不同的值以及这些值的分布是否均匀) 如果您已经有了其中一个或两个索引,那么如果不重新构造数据库,您将无能为力。如果不这样做,您可以尝试依次创建每个索引,看看它是否对查询时间有影响。如果您力所能及,您可以做的最重要的事情是重新构造数据库,以便将dim字段移动到一个单独的表中,并且该表中只有一列

对于编写的查询(这适用于具有更正的数据库结构的改进查询),您需要确定是否使用索引来解决查询。在您的情况下,最佳索引将是
(客户机,时段)
(时段,客户机)
之一,具体取决于这些索引的基数(基本上,这些列中存在多少不同的值以及这些值的分布是否均匀)


如果您已经有了其中一个或两个索引,那么如果不重新构造数据库,您将无能为力。如果不这样做,您可以尝试依次创建每个索引,看看它是否对查询时间有影响。

如果您力所能及,您可以做的最重要的事情是重新构造数据库,以便将
dim
字段移动到一个单独的表中,并且该表中只有一列
dim
(但在有多个
dim
值的情况下有多行)。此过程称为数据库规范化。然后,您可以使用单个
SELECT
执行查询,而无需将一组
SELECT
合并在一起

SELECT T.field
      ,T.Length
      ,table1.* 
FROM table1
     CROSS APPLY (
          VALUES ('dim_2', dim_2, NULL)
                ,('dim_3', dim_3, NULL)
                ,...
                ,('Length dim_2', NULL, LEN(dim_2))
                ,...
     ) AS T(field, value, Length)
WHERE table1.client = 'CL'
      AND table1.period BETWEEN @period_from AND @period_to 
      AND ((T.Length IS NOT NULL AND T.Length > @Length)
           OR (T.value IS NOT NULL AND T.value LIKE @Query))
对于编写的查询(这适用于具有正确数据库结构的改进查询),您需要确定是否正在使用索引来解决查询。在您的情况下,最佳索引将是
(客户端,句点)
(句点,客户端)
之一,具体取决于这些索引的基数(基本上,这些列中存在多少不同的值以及这些值分布的均匀程度)


如果您已经有了其中一个或两个索引,那么如果不重新构造数据库,您将无能为力。如果没有,您可以尝试依次创建每个索引,看看它是否会影响查询时间。

如果您有能力,您可以做的最重要的事情是重新构造数据库,以便移动数据库他将
dim
字段添加到一个单独的表中,并且该表中只有一个
dim
列(但对于有多个
dim
值的情况,则有多行)。此过程称为数据库规范化。然后,您将能够使用单个
选择执行查询,而无需将一组
选择组合在一起

SELECT T.field
      ,T.Length
      ,table1.* 
FROM table1
     CROSS APPLY (
          VALUES ('dim_2', dim_2, NULL)
                ,('dim_3', dim_3, NULL)
                ,...
                ,('Length dim_2', NULL, LEN(dim_2))
                ,...
     ) AS T(field, value, Length)
WHERE table1.client = 'CL'
      AND table1.period BETWEEN @period_from AND @period_to 
      AND ((T.Length IS NOT NULL AND T.Length > @Length)
           OR (T.value IS NOT NULL AND T.value LIKE @Query))
对于编写的查询(这适用于具有正确数据库结构的改进查询),您需要确定是否正在使用索引来解决查询。在您的情况下,最佳索引将是
(客户端,句点)
(句点,客户端)
之一,具体取决于这些索引的基数(基本上,这些列中存在多少不同的值以及这些值分布的均匀程度)


如果您已经有了其中一个或两个索引,那么如果不重新构造数据库,您将无能为力。如果没有,您可以尝试依次创建每个索引,看看它是否对查询时间有影响。

您可以显著减少联合数,但这项工作将进入WHERE子句。SQL查询选项miser应该明白,对于每个union语句,您只需要检查表中的行一次,因此应该更快。像这样试试看

SELECT T.field
      ,T.Length
      ,table1.* 
FROM table1
     CROSS APPLY (
          VALUES ('dim_2', dim_2, NULL)
                ,('dim_3', dim_3, NULL)
                ,...
                ,('Length dim_2', NULL, LEN(dim_2))
                ,...
     ) AS T(field, value, Length)
WHERE table1.client = 'CL'
      AND table1.period BETWEEN @period_from AND @period_to 
      AND ((T.Length IS NOT NULL AND T.Length > @Length)
           OR (T.value IS NOT NULL AND T.value LIKE @Query))
SELECT 
CASE 
 WHEN dim_2 like @query Then 'dim_2' 
 WHEN dim_3 like @query Then 'dim_3' 
 WHEN dim_4 like @query Then 'dim_4' 
 WHEN dim_5 like @query Then 'dim_5' 
 WHEN dim_6 like @query Then 'dim_6' 
 WHEN dim_7 like @query Then 'dim_7' 
 WHEN ext_inv_ref LIKE @query Then 'ext_inv_ref'
 WHEN ext_ref LIKE @query Then 'ext_ref'
END AS field, 
NULL AS Length, 
* 
FROM table1 
WHERE client = 'CL'AND period >= @period_from AND @period_to <= @period_to 
AND (dim_2 LIKE @query 
     OR dim_3 LIKE @query 
     OR dim_4 LIKE @query 
     OR dim_5 LIKE @query 
     OR dim_6 LIKE @query 
     OR dim_7 LIKE @query
     OR ext_inv_ref LIKE @query
     OR ext_ref LIKE @query)
选择
案例
当dim_2与@query相似时,则为'dim_2'
当dim_3喜欢@query时,则为'dim_3'
当dim_4喜欢@query时,则为'dim_4'
当dim_5喜欢@query时,则为'dim_5'
当dim_6与@query相似时,则为'dim_6'
当dim_7喜欢@query时,则为'dim_7'
当ext\u inv\u ref类似于@query时,则为“ext\u inv\u ref”
当ext\u ref类似于@query时,则为“ext\u ref”
以字段结尾,
长度为空,
* 
来自表1
其中client='CL'和period>=@period\u from和@period\u to@length然后是'length dim\u 2'
当dim_3不为空且len(dim_3)>@length时,则为“length dim_3”
....     
以字段结尾,
LEN(尺寸2)作为长度,
* 
来自表1
其中client='CL'和period>=@period\u from和@period\u to@length)
或
(尺寸3不为空且len(尺寸3)>@length)
或
)

您可以显著减少联合的数量,但这项工作将进入WHERE子句。SQL查询优化程序应该会发现,对于每个联合语句,您只需要检查表中的行一次,因此速度应该更快。像这样尝试一下,看看吧

SELECT 
CASE 
 WHEN dim_2 like @query Then 'dim_2' 
 WHEN dim_3 like @query Then 'dim_3' 
 WHEN dim_4 like @query Then 'dim_4' 
 WHEN dim_5 like @query Then 'dim_5' 
 WHEN dim_6 like @query Then 'dim_6' 
 WHEN dim_7 like @query Then 'dim_7' 
 WHEN ext_inv_ref LIKE @query Then 'ext_inv_ref'
 WHEN ext_ref LIKE @query Then 'ext_ref'
END AS field, 
NULL AS Length, 
* 
FROM table1 
WHERE client = 'CL'AND period >= @period_from AND @period_to <= @period_to 
AND (dim_2 LIKE @query 
     OR dim_3 LIKE @query 
     OR dim_4 LIKE @query 
     OR dim_5 LIKE @query 
     OR dim_6 LIKE @query 
     OR dim_7 LIKE @query
     OR ext_inv_ref LIKE @query
     OR ext_ref LIKE @query)
选择
案例
当dim_2与@query相似时,则为'dim_2'
当dim_3喜欢@query时,则为'dim_3'
当dim_4喜欢@query时,则为'dim_4'
当dim_5喜欢@query时,则为'dim_5'
当dim_6与@query相似时,则为'dim_6'
当dim_7喜欢@query时,则为'dim_7'
当ext\u inv\u ref类似于@query时,则为“ext\u inv\u ref”
当ext\u ref类似于@query时,则为“ext\u ref”
以字段结尾,
长度为空,
* 
来自表1
其中client='CL'和period>=@period\u from和@period\u to@length然后是'length dim\u 2'
当dim_3不为空且len(dim_3)>@length时,则为“length dim_3”
....     
以字段结尾,
LEN(尺寸2)作为长度,
* 
来自表1
其中client='CL'和period>=@period\u from和@period\u to@length)
或
(尺寸3不为空且len(尺寸3)>@length)
或
)

您可以显著减少联合的数量,但工作将进入WHERE子句。SQL查询优化程序应该知道,对于每个union语句,您只需要遍历表中的行一次,因此应该更快。像这样试试看

SELECT 
CASE 
 WHEN dim_2 like @query Then 'dim_2' 
 WHEN dim_3 like @query Then 'dim_3' 
 WHEN dim_4 like @query Then 'dim_4' 
 WHEN dim_5 like @query Then 'dim_5' 
 WHEN dim_6 like @query Then 'dim_6' 
 WHEN dim_7 like @query Then 'dim_7' 
 WHEN ext_inv_ref LIKE @query Then 'ext_inv_ref'
 WHEN ext_ref LIKE @query Then 'ext_ref'
END AS field, 
NULL AS Length, 
* 
FROM table1 
WHERE client = 'CL'AND period >= @period_from AND @period_to <= @period_to 
AND (dim_2 LIKE @query 
     OR dim_3 LIKE @query 
     OR dim_4 LIKE @query 
     OR dim_5 LIKE @query 
     OR dim_6 LIKE @query 
     OR dim_7 LIKE @query
     OR ext_inv_ref LIKE @query
     OR ext_ref LIKE @query)
选择
案例
当dim_2与@query相似时,则为'dim_2'
当dim_3喜欢@query时,则为'dim_3'
当dim_4喜欢@query时,则为'dim_4'
当dim_5喜欢@query时,则为'dim_5'
当dim_6与@query相似时,则为'dim_6'
当dim_7喜欢@query T时
/* Part 1 : We will define a function that will help us to decompose a value of a column to multiple rows */

ALTER FUNCTION [audit].[FN_Decompose](@p_liste VARCHAR (MAX), @p_separateur CHAR(1))
RETURNS  @table_result TABLE ([id] INT, [indexAt] INT, [element] VARCHAR (255) NULL)
AS
BEGIN

    DECLARE  @v_index       INT
            ,@v_i           INT
            ,@v_longueur    INT
            ,@v_element     VARCHAR(MAX)

    IF ISNULL(@p_liste, '') <> '' 
        BEGIN
            SET @v_index        = 1
            SET @v_i            = 1
            SET @v_longueur     = LEN(@p_liste) + 2
            SET @v_element      = ''

            --pour chaque caractère de la liste
            WHILE @v_index <> @v_longueur 
                BEGIN
                    --si le caractère n''est pas un séparateur
                    IF SUBSTRING(@p_liste, @v_index, 1) <> @p_separateur 
                        BEGIN
                            --Ajouter le caractère à     l''élément courant
                            SET @v_element = @v_element +     SUBSTRING(@p_liste, @v_index,1)
                        END
                    ELSE
                        BEGIN
                            --si l''élément courant n''est     pas vide
                            --IF (@v_element <> '')
                                begin
                                    --Ajout à la table
                                INSERT INTO @table_result ([id],[indexAt],element)
                                VALUES (@v_i, @v_index, @v_element)
                                --Ré-initialisation
                                SET @v_element = ''
                                SET @v_i = @v_i + 1
                            END
                    END

                -- Caractère suivant
                SET @v_index = @v_index + 1
            END
    END

INSERT INTO @table_result VALUES (@v_i, @v_index, @v_element)

RETURN

END

GO


/* THE Script */



DECLARE @period_from INT
SET @period_from = 201400

DECLARE @period_to INT
SET @period_to = 201414

Declare @length INT
Set @length = '12'

DECLARE @query VARCHAR(MAX)
SET @query = '%[^-a-zA-Z0-9() ]%';


WITH Temp AS (
SELECT   
         LEN(dim_2) AS Length_dim2
        ,LEN(dim_3) AS Length_dim3
        ,LEN(dim_4) AS Length_dim4
        ,LEN(dim_5) AS Length_dim5
    ,LEN(dim_6) AS Length_dim6
    ,LEN(dim_7) AS Length_dim7
    ,CASE WHEN dim_1 LIKE @query THEN 'dim_1' ELSE '' END+';'
    +CASE WHEN dim_2 LIKE @query THEN 'dim_2' ELSE '' END+';'
    +CASE WHEN dim_3 LIKE @query THEN 'dim_3' ELSE '' END+';'
    +CASE WHEN dim_4 LIKE @query THEN 'dim_4' ELSE '' END+';'
    +CASE WHEN dim_5 LIKE @query THEN 'dim_5' ELSE '' END+';'
    +CASE WHEN dim_6 LIKE @query THEN 'dim_6' ELSE '' END+';'
    +CASE WHEN dim_7 LIKE @query THEN 'dim_7' ELSE '' END+';'

    +CASE WHEN ext_inv_ref LIKE @query THEN 'ext_inv_ref' ELSE '' END+';'
    +CASE WHEN ext_ref LIKE @query THEN 'ext_ref' ELSE '' END+';'
    +CASE WHEN [description] LIKE @query THEN 'description' ELSE '' END+';'

    +CASE WHEN AND dim_2 is not null and len(dim_2) >@length THEN 'Length dim_2' ELSE '' END+';'
    +CASE WHEN AND dim_3 is not null and len(dim_3) >@length THEN 'Length dim_3' ELSE '' END+';'
    +CASE WHEN AND dim_4 is not null and len(dim_4) >@length THEN 'Length dim_4' ELSE '' END+';'
    +CASE WHEN AND dim_5 is not null and len(dim_5) >@length THEN 'Length dim_5' ELSE '' END+';'
    +CASE WHEN AND dim_6 is not null and len(dim_6) >@length THEN 'Length dim_6' ELSE '' END+';'
    +CASE WHEN AND dim_7 is not null and len(dim_7) >@length THEN 'Length dim_7' ELSE '' END+';' AS fields

FROM table1
WHERE client = 'CL'
AND period >= @period_from
AND @period_to <= @period_to)


SELECT

     CASE fn.element
        WHEN 'Length dim_2' THEN Length_dim2
        WHEN 'Length dim_3' THEN Length_dim3
        WHEN 'Length dim_4' THEN Length_dim4
        WHEN 'Length dim_5' THEN Length_dim5
        WHEN 'Length dim_6' THEN Length_dim6
        WHEN 'Length dim_7' THEN Length_dim7            
     END    AS [Length]
    ,fn.element AS Field
    ,t.* /* The other columns */
FROM Temp t
CROSS APPLY [audit].[FN_Decompose](fields,';') fn
WHERE fn.element IS NOT NULL
SELECT id, column_name, value
FROM   (SELECT id, period, dim_2, dim_3, dim_4, dim_5, dim_6
             , dim_7, ext_inv_ref, ext_ref, description 
        FROM myTable) a
       UNPIVOT
       (value FOR column_name 
        IN (dim_2, dim_3, dim_4, dim_5, dim_6
          , dim_7, ext_inv_ref, ext_ref, description)
       ) unpvt
WHERE (value LIKE '%[^-a-zA-Z0-9() ]%' OR len(value) > 12)
  AND period BETWEEN 201400 AND 201414