2015-03-31 28 views
0

时,我有两个表性能问题试图查询基于级联列在SQL

表1:

------------------------------- 
id | pid | name | place | num | 
------------------------------- 

表2:

------------------ 
pid | name | key | 
------------------ 

现在我正在写一个查询这是一个两列连接,一个来自table1,另一个来自table2。

select * 
from table1 join table2 
on table1.pid = table2.pid 
and table2.key + '-' + table1.num = 'ABC-123' 

由于这级联是在其再次以最扫描的行,结果两个表进行,结果取很慢,这将是预期不是瞬间。

在这种情况下,什么是明智的。谁能帮我这个。

最初它被认为是创建一个基于函数的索引,以便有一些性能增益,但我不确定这是否会有所帮助。此外,我无法在不同表格的两列上创建基于函数的索引。

新援:

给出的答案是合法的,但我觉得它会从我的实际需求了。如果我有这样的要求

select table2.key + '-' + table1.num identity 
from table1 join table2 
on table1.pid = table2.pid 

实际的要求是,我必须连接来自两个表的值并将其公开在视图中。然后任何人都可以从视图中查询该列标识。所以基本上,连接将是必须的。

+0

如果不需要所有列始终从表中选择特定的列,如从表名选择column1,column2。 – 2015-03-31 12:05:10

+0

在我看来像table2.key +' - '+ table1。num ='ABC-123'应该是不是连接条件的一部分的where子句的一部分 – 2015-03-31 14:20:01

回答

2

尝试这样,

SELECT * 
FROM table1 
     JOIN table2 
     ON table1.pid = table2.pid 
      AND table2.KEY = 'ABC' 
      AND table1.num = '123' 
+0

只需要添加由于连接原始查询中的表达式是不可连接的。指定单个谓词提供可变的表达式,因此可以有效地使用这些列上的索引。无论是使用“INNER JOIN”还是“WHERE”都没关系。可能需要使用'pid','KEY'和'num'列进行一些额外的索引调整以获得最佳性能。 – 2015-03-31 12:24:51

0

而不是使用一个字符串 'ABC-123' 尝试拆分为 'ABC' &“123'-

SELECT * 
    FROM table1 
    JOIN table2 
    ON table1.pid = table2.pid 
    AND 
    table2.key IN ('ABC') 
    AND 
    table1.num IN ('123') 
+0

代码只回答通常[皱眉](http://meta.stackoverflow.com/q/258673/2596334)。尝试添加[explinations或code comments](http://meta.stackoverflow.com/q/269981/2596334)。谢谢。 – 2015-03-31 16:55:44

0

如果你想让用户能够高效地查询连接值,您可以创建一个索引视图。其他视图列可根据需要添加。请注意0​​选件要求更新索引视图引用的表格(https://msdn.microsoft.com/en-us/library/ms191432.aspx)。如果您未使用SQL Server Enterprise或Developer Edition,则需要将NOEXPAND提示添加到查询中,以便优化程序考虑视图索引。此外,我强烈建议您避免使用保留关键字作为列名(keyidentity);

CREATE VIEW dbo.IndexedView 
WITH SCHEMABINDING 
AS 
SELECT table2.[key] + '-' + table1.num [identity] 
FROM dbo.table1 
JOIN dbo.table2 
    ON table1.pid = table2.pid; 
GO 
CREATE UNIQUE CLUSTERED INDEX cdx_IndexedView ON IndexedView([identity]); 
GO 
0

如果您一次只搜索一个值,则可以以编程方式分割值。这与其他答案类似,但会为你分裂。

CREATE PROCEDURE usp_Get_Concat_ID 
    @ConcatID AS varchar(20) 
AS 
BEGIN 
    declare @Table1Num as varchar(20) = SUBSTRING(@ConcatID, 0, CHARINDEX('-', @ConcatID)) 
    declare @Table2Key as varchar(20) = SUBSTRING(@ConcatID, CHARINDEX('-', @ConcatID)+1, LEN(@ConcatID)) 

    select * 
    from table1 join table2 
     on table1.pid = table2.pid 
     and table1.num = @Table1Num 
     and table2.key = @Table2Key 
END 
GO 

然后,您可以调用usp_Get_Concat_ID'ABC-123'。