select value
from persons p join persons2 p2
on left(p.lastname,1) = left(p2.lastname,1)
Run Code Online (Sandbox Code Playgroud)
SQL 服务器。有没有办法让这个 SARGable/运行得更快?我无法在persons 表上创建列,但我可以在persons2 上创建列。
Mar*_*ith 11
如果该lastname
列至少在其中一个表中建立索引,那么您还可以使用LIKE
SELECT *
FROM persons p
INNER JOIN persons2 p2
ON p2.lastname LIKE LEFT(p.lastname, 1) + '%'
Run Code Online (Sandbox Code Playgroud)
此计划可以在诸如左侧指定的表上进行查找。
ieON p.lastname LIKE LEFT(p2.lastname, 1) + '%'
将无法persons2
使用上面使用的索引,但可以在persons
.
然而,在两侧索引计算列的另一个答案中的建议更灵活。至于嵌套循环计划,任何一个表都可以在内部,它也允许多对多合并连接而无需排序。
使用定义为LEFT(lastname, 1)
每个表的的持久计算列在表上创建视图,然后比较计算的持久列值。
这是一个测试台,展示了如何做到这一点:
CREATE TABLE dbo.Persons
(
PersonID int NOT NULL
CONSTRAINT PK_Persons
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
, FirstName nvarchar(500) NOT NULL
, LastName nvarchar(500) NOT NULL
);
CREATE TABLE dbo.Persons2
(
PersonID int NOT NULL
CONSTRAINT PK_Persons2
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
, FirstName nvarchar(500) NOT NULL
, LastName nvarchar(500) NOT NULL
);
GO
CREATE VIEW dbo.PersonsView
WITH SCHEMABINDING
AS
SELECT p1.PersonID
, p1.FirstName
, p1.LastName
, LastNameInitial = LEFT(p1.LastName, 1)
FROM dbo.Persons p1;
GO
CREATE VIEW dbo.PersonsView2
WITH SCHEMABINDING
AS
SELECT p2.PersonID
, p2.FirstName
, p2.LastName
, LastNameInitial = LEFT(p2.LastName, 1)
FROM dbo.Persons p2;
GO
CREATE UNIQUE CLUSTERED INDEX CX_PersonsView
ON dbo.PersonsView(PersonID);
CREATE NONCLUSTERED INDEX IX_PersonsView_LastNameInitial
ON dbo.PersonsView(LastNameInitial)
INCLUDE (FirstName, LastName);
CREATE UNIQUE CLUSTERED INDEX CX_PersonsView2
ON dbo.PersonsView2(PersonID);
CREATE NONCLUSTERED INDEX IX_PersonsView2_LastNameInitial
ON dbo.PersonsView2(LastNameInitial)
INCLUDE (FirstName, LastName);
CREATE STATISTICS ST_PersonsView_001
ON dbo.PersonsView(LastName);
CREATE STATISTICS ST_PersonsView2_001
ON dbo.PersonsView2(LastName);
Run Code Online (Sandbox Code Playgroud)
在这里,我们将插入一些示例数据:
INSERT INTO dbo.Persons(FirstName, LastName)
VALUES ('Max', 'Vernon')
, ('Joe', 'Black');
INSERT INTO dbo.Persons2(FirstName, LastName)
VALUES ('Max', 'Vernon')
, ('Joe', 'Black');
Run Code Online (Sandbox Code Playgroud)
这是SELECT
查询:
SELECT *
FROM dbo.PersonsView pv1
INNER JOIN dbo.PersonsView2 pv2 ON pv1.LastNameInitial = pv2.LastNameInitial;
Run Code Online (Sandbox Code Playgroud)
结果:
+-----------+-----------+----------+-------------- ---+-----------+-----------+-----------+------------- ----+ | 人名 | 名字 | 姓氏 | 姓氏首字母 | 人名 | 名字 | 姓氏 | 姓氏首字母 | +-----------+-----------+----------+-------------- ---+-----------+-----------+-----------+------------- ----+ | 2 | 乔| 黑色 | 乙 | 2 | 乔| 黑色 | 乙 | | 1 | 最大 | 弗农 | V | 1 | 最大 | 弗农 | V | +-----------+-----------+----------+-------------- ---+-----------+-----------+-----------+------------- ----+
执行计划,每个表只有两行(当然行数不多!)
归档时间: |
|
查看次数: |
212 次 |
最近记录: |