简体   繁体   中英

Different productivity on view with WHERE clause

I've encountered an issue with productivity using the View limited with WHERE clause.

This code works immediately:

SELECT TOP(20) 
    m.Id, 
    m.Specs, 
    m.DefaultName, 
    m.NameLT, 
    m.NameEN, 
    m.NameTR
FROM multilang.vwOEvent AS m
WHERE CHARINDEX(N'we', m.NameEN) > 0

But when I'm using for example WHERE CHARINDEX(N'we', m.NameLT) > 0 - using the similar but another field, I encounter with large (up to 30 seconds) delay.

The view is following:

CREATE VIEW multilang.vwOEvent
AS SELECT 
        a.EventID AS ID,
        a.Specs, 
        a.[Name] AS DefaultName, 
        lngEN.[Name] AS NameEN, 
        lngTR.[Name] AS NameTR, 
        lngAA.[Name] AS NameAA
    FROM      game.vwActiveOEvents a
    LEFT JOIN translation.OEvent lngEN ON lngEN.Specs = a.Specs and lngEN.LanguageID = 1
    LEFT JOIN translation.OEvent lngTR ON lngTR.Specs = a.Specs and lngTR.LanguageID = 2
    LEFT JOIN translation.OEvent lngAA ON lngAA.Specs = a.Specs and lngAA.LanguageID = 3
GO

The indexes on translation.OEvent are created. Additional code is obvious:

CREATE TABLE translation.OEvent (
    ID     BIGINT IDENTITY,
    LangID TINYINT NOT NULL,
    Specs  VARCHAR(300) NOT NULL,
    [Name] NVARCHAR(200) NOT NULL
    CONSTRAINT PK_translation_OEvent_ID PRIMARY KEY CLUSTERED (ID)
) ON [PRIMARY]
GO

CREATE UNIQUE INDEX UX_OEvent
ON translation.OEvent (LangID, Specs)
INCLUDE ([Name])
ON [PRIMARY]
GO

CREATE TABLE game.OEvent (
    ID     INT IDENTITY,
    Specs  VARCHAR(300) NOT NULL,
    [Name] NVARCHAR(200) NOT NULL,
    IDT    DATETIME2 NOT NULL,
    CONSTRAINT PK_game_OEvent PRIMARY KEY CLUSTERED (ID)
) ON [PRIMARY]
GO

CREATE VIEW game.vwActiveOEvents
AS SELECT
        ID
        Specs
        [Name]
    FROM game.OEvent
    WHERE IDT > GETDATE()
GO

Will appreciate any advice and solutions. Index on view? Rebuilding of views?

The code is simplified, of course, but the removed parts contain business logic so are not interesting here.

The difference in time is due to one of two factors:

  • You may be measuring the time to the first row being returned, rather than to the last.
  • The data volume associated with the different names might be radically different.

As mentioned in the comments, the where clause cannot use an index, due to the charindex() function. That said, it would more colloquially be written using LIKE :

m.NameEN LIKE N'%we%'

However, that won't affect performance.

What can you do? There are really no totally general solutions. But here are some ideas:

  • If you are really looking for exact equality, use = . That is much more efficient.
  • If you are always looking for the same string 'we' , then you can use a computed column.
  • If you are looking for a "word" in the string, then you can use a full-text index.

It is not clear if any of those conditions apply.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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