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