![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Эффективность плана выполнения запроса [MSSQL]
Bless © (2005-04-25 16:59:00)Проблема вот в чем.
В пятницу, после жалоб на жуткие тормоза, я посмотрел на план выполнения одного запроса (выборка)
(который эти тормоза провоцировал).
Оказалось, что этот план (сгенерированный самим MS SQL, там нет никаких хинтов) - на редкость неудачный.
Потанцевав немного с бубном, решил перегрузить сервер. После перезагрузки сделал заодно полный BACKUP базы.
Это (перезагрузка) не помогло. Но тут к счастью вскоре закончился рабочий день. :)
В понедельник же тормозов - как и не бывало. Посмотрел на план выполнения - он стал совсем другим!
Я из сделанного накануне backup-а сделал себе тестовую копию базы данных.
И выполнил в ней этот же запрос. В результате - те же тормоза и тот же фиговый план выполнения, что и в пятницу.
Чем это можно объяснить?
Nikolay M. (2005-04-29 15:51:00) [1]
> Спасибо за инфу. И за предыдущие тоже. :)
Да на здоровье. Тема неисчерпаема, на самом деле :)
> Lord Zmiy © (29.04.05 12:44) [33]
Сказал, что газы пустил... Купи себе жвачку.
Bless (2005-04-29 14:54:00) [2]Nikolay M.[32]>
Спасибо за инфу. И за предыдущие тоже. :)
Вопросов больше нет. На досуге поразбираюсь, что же это все-таки было (ведь в рабочей базе все само прошло к понедельнику, так что дело все-таки не в ключе). Благо теперь есть куда думать. Спасибо.
Lord Zmiy[33]>
>автор просто сказачник
Думаешь, я все придумал? А я ж еще не все говорил, чтоб меня совсем идиотом не посчитали. :)
1)
В [5], в неэффективном плане в пункте 4) на выходе действительно была 91 запись. Вот только через раз. А через другой раз - более 2 000 000 записей. Хотя и на конечный результат это никак не влияло, и последующий select * from #p давал 91 запись, как и положено.
2)
В тестовой базе тоже все прошло само собой (по-моему в среду) и мне пришлось еще раз восстановиться из BACKUP-а, чтоб мочь исследовать этот неприятный эффект.
>такого увлекательного сабжа еще не читал :)
Можешь выслать мне гонорар :)
Lord Zmiy (2005-04-29 12:44:00) [3]аааааааааа знаю .... это БУБЕН ПОМОГ :)
автор просто сказачник такого увлекательного сабжа еще не читал :)
жаль только помочь ничем не могу такой проблемы не возникало :) и как с ней бороться соответственно не знаю
Nikolay M. (2005-04-29 11:22:00) [4]
> dbcc traceon(3604)
Имхо, это рудимент, оставшийся от Sybase и потому недокументированный в SQL Server 2000.
http://www.cybersecurity.ru/manuals/data/mssql/1924.html
Флаг трассировки 3604 заставляет сервер передавать отладочную информацию в текущее соединение непосредственно клиенту
> dbcc tab(@db_id, @tbl_id)
http://www.sql.ru/subscribe/005.shtml
Bless (2005-04-29 11:04:00) [5]> http://blogs.gotdotnet.ru/personal/Bezzus/PermaLink.aspx?guid=
>2ec662e4-9179-4663- 8034-3f54bf198db9
Полезная статья.
Правда, что-то я в BOL ничего не нашел по поводу
dbcc traceon( 3604 )
dbcc tab(@db_id, @tbl_id)
Nikolay M. (2005-04-29 11:04:00) [6]
> Fay ©
Один в один ветка :)
http://www.sql.ru/forum/actualthread.aspx?tid=180382
Nikolay M. (2005-04-28 20:42:00) [7]
> автор поленился подумать над значением слов 'уникальный
> индекс'
Тем не менее полезность статьи от этого не уменьшилась. К тому же автор прав: кластерный индекс действительно имеет дело с уникальными значениями, просто они не всегда в точности равны значениям индексируемого поля из таблицы.
Fay (2005-04-28 20:29:00) [8]Nikolay M. © (28.04.05 19:37) [27]
> Если существуют записи с одинаковыми значениями, SQL
> Server делает их уникальными, добавляя номера из
> внутреннего (невидимого снаружи) счетчика.
Может лучше сказать "автор поленился подумать над значением слов 'уникальный индекс'"?
P.S.
"Телега ..." намного интереснее.
Nikolay M. (2005-04-28 19:37:00) [9]
> Fay © (28.04.05 18:26) [26]
> >> В SQL Server кластерный индекс является уникальным индексом
> по определению.
> Бред
Может лучше сказать "я поленился внимательно прочитать текст до конца"? Эту статью прочитала не одна сотня человек, вряд-ли в ней может быть допущена настолько грубая ошибка. Неоднозначность такой формулировки - да, возможно, но дальше подробно описывается, что конкретно имеется ввиду.
Если существуют записи с одинаковыми значениями, SQL Server делает их уникальными, добавляя номера из внутреннего (невидимого снаружи) счетчика.
Fay (2005-04-28 18:26:00) [10]2 Nikolay M. © (28.04.05 17:48) [25]
>Да, вот еще очень полезная статья, не сразу ее нашел:
> http://www.sql.ru/articles/mssql/03013101Indexes.shtml
>> В SQL Server кластерный индекс является уникальным индексом по определению.
Бред
Nikolay M. (2005-04-28 17:48:00) [11]Да, вот еще очень полезная статья, не сразу ее нашел:
http://www.sql.ru/articles/mssql/03013101Indexes.shtml
Nikolay M. (2005-04-28 17:41:00) [12]
> В [5] же написано:
>
> SELECT nzz INTO #p
> FROM pozib WHERE nzs=@nzs
Проглядел. 91 - видимо, записей, а не полей. Да, на такой таблице индексы, скорее всего, будут лишними.
> Я после того, как сюда запостил, сделал первичный ключ в
> pozib_m кластерным и все заработало. Хотя пусть меня покрасят,
> если я понимаю почему.
> Может ты знаешь? :)
Сначала немного личного опыта: я почти во всех таблицах делаю ПК Identity+Clustered, исключение составляют таблицы, на которые не ссылаются другие таблицы или элементарные справочники типа (ID, WorkDate). Что касается твоего случая, могу предположить, что таблица активно участвует а апдейтах-инсертах-дилитах, а поскольку кластерный индекс у тебя отсутствовал, то индексы были основаны на RowID, а как он себя ведет при активной работе с таблицей - мне лично неведомо. Создание кластерного индекса и, как следствие, перестройка всех остальных индексов расставила все по местам. Полистай на досуге:
http://blogs.gotdotnet.ru/personal/Bezzus/PermaLink.aspx?guid=2ec662e4-9179-4663-8034-3f54bf198db9
http://blogs.gotdotnet.ru/personal/AlexGaas/PermaLink.aspx?guid=1c2fcc75-f9ad-4bd1-afe0-3ddc3209bcf9
Bless (2005-04-28 17:19:00) [13]>А почему бы не сделать ПК кластерным?
Вопрос как раз вовремя :)
Я после того, как сюда запостил, сделал первичный ключ в pozib_m кластерным и все заработало. Хотя пусть меня покрасят, если я понимаю почему.
Может ты знаешь? :)
В [5] же написано:
SELECT nzz INTO #p
FROM pozib WHERE nzs=@nzs
nzz- целочисленное поле. И полей всего 91
>А на shapb_m_cache вообще индексов нет?
В нее часто вставляют/удаляют. Кроме того она небольшая, в средней 100-300 записей.
Fay [18]>
Эт моё творчество :)
Nikolay M. (2005-04-28 17:06:00) [14]
> Fay © (28.04.05 16:10) [21]
> Nikolay M. © (28.04.05 16:04) [20]
> Зачем!?
Чтобы, во-первых, связка с другими таблицами, ссылающимися на данную происходила по кластерному индексу, а, во-вторых, чтобы все прочие индексы в таблице также строились на основе кластерного индекса.
Fay (2005-04-28 16:10:00) [15]Nikolay M. © (28.04.05 16:04) [20]
Зачем!?
Nikolay M. (2005-04-28 16:04:00) [16]
> ALTER TABLE [dbo].[shapb_m_cache] WITH NOCHECK ADD
> CONSTRAINT [DF_shapb_m_cache_comp_name] DEFAULT (host_name())
> FOR [comp_name],
> CONSTRAINT [DF_shapb_m_cache_st] DEFAULT (0) FOR [st],
> CONSTRAINT [DF_shapb_m_cache_state] DEFAULT (0) FOR [modi],
> CONSTRAINT [DF_shapb_m_cache_del] DEFAULT (0) FOR [del],
> CONSTRAINT [PK_shapb_m_cache] PRIMARY KEY NONCLUSTERED
>
> (
> [nzz]
> ) ON [PRIMARY
А почему бы не сделать ПК кластерным?
Nikolay M. (2005-04-28 15:56:00) [17]
> Fay © (28.04.05 15:47) [18]
> real_low, real_high ?
Я просто int поставил :)
> SELECT * FROM pozib_m pm
> INNER JOIN shapb_m_cache s ON pm.nzm=s.nzm
> WHERE s.nzs=@nzs AND s.comp_name=@comp AND s.indi<>1
> AND pm.nzp IN (SELECT nzz FROM #p) AND s.del<>1
А на shapb_m_cache вообще индексов нет? И какова структура #p?
Fay (2005-04-28 15:47:00) [18]real_low, real_high ?
Bless (2005-04-28 14:17:00) [19]
CREATE TABLE [dbo].[shapb_m_cache] (
[nzz] [int] IDENTITY (1, 1) NOT NULL ,
[comp_name] [nchar] (30) COLLATE SQL_Latin1_General_CP1251_CI_AS NOT NULL ,
[nzs] [int] NOT NULL ,
[nzm] [varchar] (30) COLLATE SQL_Latin1_General_CP1251_CI_AS NOT NULL ,
[indi] [smallint] NOT NULL ,
[ob] [real_high] NULL ,
[st] [float] NOT NULL ,
[ozen] [float] NULL ,
[tzen] [float] NULL ,
[zsr] [float] NULL ,
[modi] [smallint] NOT NULL ,
[del] [bit] NOT NULL
) ON [PRIMARY]
CREATE TABLE [dbo].[Pozib_M] (
[nzz] [int] IDENTITY (1, 1) NOT NULL ,
[nzp] [int] NOT NULL ,
[indi] [smallint] NOT NULL ,
[znak] [varchar] (2) COLLATE SQL_Latin1_General_CP1251_CI_AS NULL ,
[nzm] [varchar] (20) COLLATE SQL_Latin1_General_CP1251_CI_AS NULL ,
[norma] [float] NOT NULL ,
[st] [real_low] NULL ,
[ozen] [real_low] NULL ,
[tzen] [real_low] NULL ,
[zsr] [real_low] NULL
) ON [PRIMARY]
ALTER TABLE [dbo].[shapb_m_cache] WITH NOCHECK ADD
CONSTRAINT [DF_shapb_m_cache_comp_name] DEFAULT (host_name()) FOR [comp_name],
CONSTRAINT [DF_shapb_m_cache_st] DEFAULT (0) FOR [st],
CONSTRAINT [DF_shapb_m_cache_state] DEFAULT (0) FOR [modi],
CONSTRAINT [DF_shapb_m_cache_del] DEFAULT (0) FOR [del],
CONSTRAINT [PK_shapb_m_cache] PRIMARY KEY NONCLUSTERED
(
[nzz]
) ON [PRIMARY]
ALTER TABLE [dbo].[Pozib_M] WITH NOCHECK ADD
CONSTRAINT [DF_Pozib_M_st] DEFAULT (0) FOR [st],
CONSTRAINT [PK_Pozib_M] PRIMARY KEY NONCLUSTERED
(
[nzz]
) ON [PRIMARY]
CREATE INDEX [pozib_m_nzp_index] ON [dbo].[Pozib_M]([nzp]) ON [PRIMARY]
CREATE INDEX [pozib_m_nzm] ON [dbo].[Pozib_M]([nzm]) ON [PRIMARY]
Nikolay M. (2005-04-28 09:36:00) [20]
> Bless © (27.04.05 09:50) [15]
Приведи скрипты на создание всех таблиц, включая индексы.