Поиск в таблице журналов с несколькими измерениями - PullRequest
1 голос
/ 04 февраля 2010

Я пытаюсь найти более производительный способ поиска в таблице журналов. Таблица регистрирует все поисковые запросы, выполненные на сайте, и может содержать несколько фильтров по одному критерию. Например, пользователи могут искать дома в нескольких округах и несколько типов недвижимости в одном поиске. Мне нужно иметь возможность запустить отчет, чтобы узнать, сколько пользователей искали в конкретном округе / округах с определенным типом / типами свойств. Поиски в настоящее время регистрируются в следующих таблицах:

Хранит определения размеров для поиска:

    CREATE TABLE [dbo].[LogSearchDimensions](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [VarName] [nvarchar](50) NOT NULL,
    [Label] [nvarchar](50) NOT NULL,
    [Description] [nvarchar](1024) NOT NULL,
    [Created] [datetime] NOT NULL,
 CONSTRAINT [PK_LogSearchDimensions] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

Пример данных:

ID          VarName                                            Label
----------- -------------------------------------------------- --------------------------------------------------
3           City_ID                                            City ID
5           County_ID                                          County ID
7           PageNum                                            Page Number
8           PriceLow                                           Lowest Price
9           PriceHigh                                          Highest Price
10          Region_ID                                          Region ID
11          Site_ID                                            Site ID
14          AcreLow                                            Lowest Acreage
15          AcreHigh                                           Highest Acreage
16          State_ID                                           State ID
17          Style                                              Style
18          SiteStateID                                        Site State ID
19          Distance                                           Distance
20          FIPS                                               FIPS Code

Хранит информацию первичного поиска, например, когда был выполнен поиск и кто его выполнял:

CREATE TABLE [dbo].[LogSearches](
    [ID] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
    [RecordCount] [int] NOT NULL,
    [PageNumber] [int] NOT NULL,
    [IPAddress] [varchar](15) NOT NULL,
    [Domain] [nvarchar](150) NOT NULL,
    [ScriptName] [nvarchar](500) NOT NULL,
    [QueryString] [varchar](max) NULL,
    [Referer] [nvarchar](1024) NOT NULL,
    [SearchString] [nvarchar](max) NOT NULL,
    [UserAgent] [nvarchar](2048) NULL,
    [Processed] [datetime] NOT NULL,
    [Created] [datetime] NOT NULL,
    [IntegerIP] [int] NULL,
 CONSTRAINT [PK_LogSearches] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

Сохраняет размеры для каждого поиска. Это может быть одна запись или 50, в зависимости от выполненного поиска:

CREATE TABLE [dbo].[LogSearchesDimensions](
    [ID] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
    [LogSearch_ID] [numeric](18, 0) NOT NULL,
    [LogSearchDimension_ID] [int] NOT NULL,
    [SearchValue] [bigint] NULL,
 CONSTRAINT [PK_LogSearchesDimensions] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[LogSearchesDimensions]  WITH CHECK ADD  CONSTRAINT [FK_LogSearchesDimensions_LogSearchDimensions] FOREIGN KEY([LogSearchDimension_ID])
REFERENCES [dbo].[LogSearchDimensions] ([ID])
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[LogSearchesDimensions] CHECK CONSTRAINT [FK_LogSearchesDimensions_LogSearchDimensions]
GO

ALTER TABLE [dbo].[LogSearchesDimensions]  WITH CHECK ADD  CONSTRAINT [FK_LogSearchesDimensions_LogSearches] FOREIGN KEY([LogSearch_ID])
REFERENCES [dbo].[LogSearches] ([ID])
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[LogSearchesDimensions] CHECK CONSTRAINT [FK_LogSearchesDimensions_LogSearches]
GO

В таблице LogSearchesDimensions у меня может быть несколько записей для County_ID (LogSearchDimension_id 5), если пользователь выполнил поиск более одного округа в одном поиске. Предположим, что пользователь выполнил поиск в округах 5, 6, 7, 12 и 15. Когда я запускаю отчет, этот одиночный поиск должен отображаться в отчетах по всем 5 округам, в которых проводился поиск. Если я запустил отчет, объединяющий округа 5 и 6, он должен отображаться только один раз.

Я знаю, что это много информации, и, вероятно, все еще недостаточно, но я надеюсь, что кто-то, кто сделал подобное, мог бы поделиться некоторыми советами, как заставить этот тип фильтра работать с некоторой степенью скорости.

В настоящее время у меня очень сложный запрос со всеми видами объединений и условиями для поиска поисков с соответствующим количеством совпадений, но он неэффективен вообще. Я приложил диаграмму таблиц, чтобы показать отношения. alt text
(источник: dansshorts.com )

Я сейчас ищу, используя следующие методы:

CREATE VIEW [dbo].[vwLogSearchesCounty]
AS
SELECT     dbo.LogSearches.ID, CAST(FLOOR(CAST(dbo.LogSearches.Created AS FLOAT)) AS DATETIME) AS Created, C.county, C.County_ID, S.state, S.state_ID
FROM         dbo.LogSearches WITH (NOLOCK) INNER JOIN
                      dbo.LogSearchesDimensions AS D WITH (NOLOCK) ON dbo.LogSearches.ID = D.LogSearch_ID AND D.LogSearchDimension_ID = 5 INNER JOIN
                      propertyControlCenter.dbo.county AS C WITH (NOLOCK) ON C.County_ID = D.SearchValue INNER JOIN
                      propertyControlCenter.dbo.state AS S WITH (nolock) ON C.state_ID = S.state_ID


DECLARE @LowDate DATETIME, @HighDate DATETIME;   
SET @LowDate = '2010-01-01'  ;   
SET @HighDate = '2010-02-01' ;         
SELECT     
    CONVERT(varchar, Created, 107) AS displayDate     
    , County     , County_ID     
    , reportCount    
FROM (     
    SELECT      
        Created      
        , County_ID      , County      , reportCount      
        , DENSE_RANK() OVER(ORDER BY MaxRecords DESC, County) AS theRank     
        FROM (      
            SELECT       
                v.County_ID               
                , v.Created              
                , C.county + ' County, ' + S.State_Code AS County       
                , COUNT(DISTINCT v.ID) AS reportCount       
                , MAX(COUNT(DISTINCT v.ID)) OVER(PARTITION BY v.County_ID) AS MaxRecords      
            FROM       
                vwLogSearchesCounty v (NOLOCK)       
                INNER JOIN propertyControlCenter.dbo.county C (NOLOCK) ON        
                    v.County_ID = C.County_ID        
                    AND v.Created BETWEEN @LowDate AND @HighDate                 
                    AND c.State_ID = 48         
                INNER JOIN propertyControlCenter.dbo.state S (NOLOCK) ON C.state_ID = S.state_ID       
                INNER JOIN LogSearchesDimensions D (NOLOCK) ON v.ID = D.LogSearch_ID AND D.LogSearchDimension_ID IN (8, 9, 14, 15, 17)      
                WHERE       
                    1 = 0               
                    OR (         
                        D.LogSearchDimension_ID = 17         
                        AND D.SearchValue IN (2,5,6 )        
                    )             
                GROUP BY               
                    v.Created              
                    , v.County_ID       
                    , C.County       
                    , S.State_Code              
                HAVING COUNT(v.ID) >=  3       ) d     
                GROUP BY      
                    Created      
                    , County      
                    , County_ID      
                    , reportCount      
                    , MaxRecords     ) 
                ranking     
                WHERE theRank <= 5     
ORDER BY theRank, County_ID, Created

Текущее количество записей: LogSearches: 8 970 000 LogSearchesDimensions: 37 630 000

Выполнение указанного запроса занимает 24 секунды (слишком долго для наших целей) и возвращает следующие данные:

displayDate                    County                                                                                                                                                                                                            County_ID   reportCount
------------------------------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------- -----------
Jan 01, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        49
Jan 02, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        84
Jan 03, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        76
Jan 04, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        118
Jan 05, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        92
Jan 06, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        59
Jan 07, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        45
Jan 08, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        84
Jan 09, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        71
Jan 10, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        91
Jan 11, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        67
Jan 12, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        52
Jan 13, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        76
Jan 14, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        104
Jan 15, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        69
Jan 16, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        51
Jan 17, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        105
Jan 18, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        76
Jan 19, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        72
Jan 20, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        69
Jan 21, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        32
Jan 22, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        54
Jan 23, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        60
Jan 24, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        76
Jan 25, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        95
Jan 26, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        73
Jan 27, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        64
Jan 28, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        57
Jan 29, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        41
Jan 30, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        87
Jan 31, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        67
Feb 01, 2010                   Bastrop County, TX                                                                                                                                                                                                6218        66
Jan 01, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        51
Jan 02, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        70
Jan 03, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        69
Jan 04, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        74
Jan 05, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        44
Jan 06, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        60
Jan 07, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        37
Jan 08, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        39
Jan 09, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        40
Jan 10, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        71
Jan 11, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        63
Jan 12, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        54
Jan 13, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        51
Jan 14, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        46
Jan 15, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        54
Jan 16, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        45
Jan 17, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        73
Jan 18, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        70
Jan 19, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        30
Jan 20, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        57
Jan 21, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        59
Jan 22, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        43
Jan 23, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        49
Jan 24, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        72
Jan 25, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        86
Jan 26, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        43
Jan 27, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        69
Jan 28, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        57
Jan 29, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        46
Jan 30, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        52
Jan 31, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        107
Feb 01, 2010                   Montgomery County, TX                                                                                                                                                                                             6199        40
Jan 01, 2010                   Fayette County, TX                                                                                                                                                                                                6240        58
Jan 02, 2010                   Fayette County, TX                                                                                                                                                                                                6240        65
Jan 03, 2010                   Fayette County, TX                                                                                                                                                                                                6240        50
Jan 04, 2010                   Fayette County, TX                                                                                                                                                                                                6240        61
Jan 05, 2010                   Fayette County, TX                                                                                                                                                                                                6240        52
Jan 06, 2010                   Fayette County, TX                                                                                                                                                                                                6240        48
Jan 07, 2010                   Fayette County, TX                                                                                                                                                                                                6240        44
Jan 08, 2010                   Fayette County, TX                                                                                                                                                                                                6240        40
Jan 09, 2010                   Fayette County, TX                                                                                                                                                                                                6240        25
Jan 10, 2010                   Fayette County, TX                                                                                                                                                                                                6240        56
Jan 11, 2010                   Fayette County, TX                                                                                                                                                                                                6240        51
Jan 12, 2010                   Fayette County, TX                                                                                                                                                                                                6240        47
Jan 13, 2010                   Fayette County, TX                                                                                                                                                                                                6240        43
Jan 14, 2010                   Fayette County, TX                                                                                                                                                                                                6240        47
Jan 15, 2010                   Fayette County, TX                                                                                                                                                                                                6240        43
Jan 16, 2010                   Fayette County, TX                                                                                                                                                                                                6240        37
Jan 17, 2010                   Fayette County, TX 

1 Ответ

0 голосов
/ 05 февраля 2010

Предварительный анализ эффективности:

Основные замечания и рекомендации:

Похоже, что

  1. это хранилище данных (все представленное соответствует DW), а
  2. это было реализовано в базе данных SQL Server OLTP.

Следовательно, лучшее, что вы могли бы сделать, это:

0. Повторно внедрите его в базу данных OLAP SQL Server:

Базы данных OLAP (или службы Analysis Services или SSAS) намного лучше подходят для такого типа приложений и намного лучше оптимизированы для этого типа запросов. Однако, исходя из предположения, что это далеко выходит за рамки ваших текущих намерений, я перейду к рекомендациям с более низким воздействием.

Предварительные замечания и рекомендации:

это обязательно предварительные данные, поскольку анализ реальной производительности не может быть выполнен для чего-то такого сложного без хотя бы предполагаемого плана запроса. В частности, хотя рекомендации для возможных улучшений могут быть сделаны без реальных данных или планов запросов, основанных на реальных данных, невозможно сказать, какие изменения действительно повлияют на производительность.

Основная проблема, которую я вижу, заключается в том, что этот очень сложный запрос выполняет много операций сканирования полной таблицы, и из-за его сложности почти 10 * * форсирует эти проверки. Сканирование таблицы может быть очень дорогим, особенно на больших столах. Однако, если для SQL не существует эффективного способа предварительной фильтрации таблицы (то есть удалить 99% записей с помощью теста, который не требует объединения и может быть применен к индексу), то это наиболее эффективный выбор, который он оставил. В свете этого в следующих рекомендациях рассматриваются пути исправления этой ситуации:

A. Создайте столбец SARGable [Created] в представлении [vwLogSearchesCounty].

В настоящее время представление [vwLogSearchesCounty] определяет свой столбец [Создано] следующим образом:

CAST(FLOOR(CAST(dbo.LogSearches.Created AS FLOAT)) AS DATETIME) AS Created

Очевидная причина этого - разрешить использование оператора BETWEEN в этом столбце при поиске диапазонов дат без необходимости беспокоиться о проблемах несоответствия времени дня. Однако это имеет побочный эффект, заключающийся в том, что этот столбец не может быть SARGable, то есть недоступен для поиска по индексу ("SARG" = "Search ARGument"). Поскольку поиск в этом столбце является одним из немногих глобально фиксированных ограничений (то есть что-то, что можно искать на до выполнения соединений), то сделать его SARGable - одна из ваших лучших возможностей для ускорения ваших запросов.

Чтобы сделать SARGable, вам нужно сделать следующее:

  1. Либо удалите функцию CAST (FLOOR (CAST (..))) из столбца [Created], либо добавьте второй столбец к представлению без них (я буду предполагать позднее), например:

    dbo.LogSearches.Created AS CreatedTime
    
  2. Измените поиск диапазона дат в представлении, как показано ниже, с

    AND v.Created BETWEEN @LowDate AND @HighDate
    

    до

    AND v.CreatedTime >= @LowDate AND v.CreatedTime < dateadd(dd,1,@HighDate)
    
  3. Убедитесь, что в исходном столбце [Создано] есть индекс. Кластерный индекс будет лучше всего:

    CREATE CLUSTERED INDEX IX_LogSearches_Created ON [dbo].[LogSearches] (Created)
    

(подробнее о правильном поиске дат и диапазонов дат в SQL Server см. Здесь: http://www.sqlservercentral.com/Forums/Topic438717-338-1.aspx)

B. Сделайте столбец [LogSearchDimension_ID] в таблице [LogSearchesDimensions] проиндексированным.

Я не знаю, был ли этот столбец уже проиндексирован, но так и должно быть, поскольку это еще одно из очень немногих глобально фиксированных ограничений. Опять же, лучше всего использовать кластеризованный индекс:

CREATE CLUSTERED INDEX IX_LogSearchesDimensions_11 ON [dbo].[LogSearchesDimensions] ([LogSearchDimension_ID])

C. Сделайте столбец [State_code] в таблице [State] проиндексированным.

Как и (B) выше, он не может быть проиндексирован, но ваш запрос, вероятно, выиграет, если он будет.

D. Исключите из запроса явные таблицы [County] и [State].

Похоже, что единственная причина, по которой вы явно объединяете таблицы [County] и [State] в своем запросе, состоит в том, чтобы получить столбец [State_Code] из таблицы [State], который не включен в представление [vwLogSearchesCounty] , В идеале оптимизатор должен выяснить, что он может объединить эти две ссылки на таблицы [State] и [County], и вы можете получить этот столбец бесплатно. К сожалению, оптимизатор часто пропускает такие вещи в более сложных запросах, и на моем сервере он выполняет двойную работу для этого поля.

Лучшим решением было бы просто добавить столбец [State_code] в представление, а затем исключить явные объединения [county] и [State] в вашем запросе. этот дополнительный столбец должен , а не влиять на производительность любых других запросов, которые используют представление, но не используют этот столбец (SQL Server 2005 и выше).

Если вы реализуете все четыре из этих рекомендаций (включая часть CLUSTERED), вы сможете исключить сканирование таблицы. В настоящее время я не вижу другого разумного способа сделать это.

Более подробная рекомендация:

Если вам все это не поможет, я могу увидеть только еще один сравнительно недорогой вариант - превратить ваше представление [vwLogSearchesCounty] в индексированное представление. В частности, индексы, о которых я упоминал выше в [State_Code] и [Created] / [CreatedTime], должны быть переопределены в представлении (как и любые другие важные).

Это дает эффект не только индексации важных полей, но также предварительной агрегации представления и автоматического поддержания этой предварительной агрегации. Это также означает, что он займет место для хранения, поэтому, если в этом представлении слишком много строк, это может быть проблемой для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...