Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 временные таблицы как правильно делать?  [new]
Badhabit
Member

Откуда:
Сообщений: 90
День добрый. У меня вопрос по временным таблицам. Мне для лучшего понимания алгоритма удобно разбивать запрос на много мелких подзапросов и оформлять их результаты "временными" таблицами, а потом в результирующем запросе выбирать уже из них. Делаю это примерно так:
with Tbl1 as
(
select * from zzz
),
Tbl2 as
(
select * from Tbl1 left join xxx on xxx.fld1 = tbl1.fld
),
tbl3 as
(
 select ....
)

select * from tbl1
left join tbl2 on ...
left join tbl3 on ...

Подскажите так правильно делать, в смысле использовать with (я просто где-то увидел такую конструкцию и пользую ее, но есть подозрение что это не совсем правильно)? Может быстрее/оптимальнее использовать временные таблицы объявленные чрез declare (может запросы будут выполняться быстрее)? Или и так все ок?
8 дек 16, 09:55    [19979034]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
Дедушка
Member

Откуда: Город трёх революций
Сообщений: 5115
with это синтаксический сахар.
при выполнении вашего последнего селекта все участвующие в нём cte заменятся на их текст (будет куча вложенных подзапросов).
замена cte на явные временные таблицы в большинстве случаев приводит к увеличению производительности.
8 дек 16, 10:01    [19979074]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
Badhabit
Member

Откуда:
Сообщений: 90
Дедушка
with это синтаксический сахар.
при выполнении вашего последнего селекта все участвующие в нём cte заменятся на их текст (будет куча вложенных подзапросов).
замена cte на явные временные таблицы в большинстве случаев приводит к увеличению производительности.

Ясно.
А как правильно объявить временную таблицу? Через declare @tbl table(....)? Или есть какое-то объявление через #...
Надо ли в конце запроса ее удалять как-то или это произойдет автоматом?
Как правильно в нее записать много данных? Есть же select into и insert into...
8 дек 16, 10:22    [19979178]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
Badhabit
Дедушка
with это синтаксический сахар.
при выполнении вашего последнего селекта все участвующие в нём cte заменятся на их текст (будет куча вложенных подзапросов).
замена cte на явные временные таблицы в большинстве случаев приводит к увеличению производительности.

Ясно.
А как правильно объявить временную таблицу? Через declare @tbl table(....)? Или есть какое-то объявление через #...
Надо ли в конце запроса ее удалять как-то или это произойдет автоматом?
Как правильно в нее записать много данных? Есть же select into и insert into...

неужели мсдн заблокирован? возмутитесь, пусть вам разрешат читать!
https://technet.microsoft.com/ru-ru/library/ms177399(v=sql.105).aspx
8 дек 16, 10:24    [19979189]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
Badhabit
Member

Откуда:
Сообщений: 90
Почитал) Правильно я понял, что для относительно больших (> 20к строк) временных таблиц оптимальнее использовать временные таблицы и добавлять туда данные так:
SELECT * INTO #tmp FROM myTable;

Еще вопрос. Нужно ли делать индексы по полям больших временных таблиц для ускорения последующих запросов?
8 дек 16, 10:36    [19979259]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Badhabit
Почитал) Правильно я понял, что для относительно больших (> 20к строк) временных таблиц оптимальнее использовать временные таблицы и добавлять туда данные так:
SELECT * INTO #tmp FROM myTable;


Еще вопрос. Нужно ли делать индексы по полям больших временных таблиц для ускорения последующих запросов?
SELECT ... INTO - это создание новой таблицы с заполнением данными, а не INSERT в существующую.
8 дек 16, 10:47    [19979333]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
Badhabit
Member

Откуда:
Сообщений: 90
iap
Badhabit
Почитал) Правильно я понял, что для относительно больших (> 20к строк) временных таблиц оптимальнее использовать временные таблицы и добавлять туда данные так:
SELECT * INTO #tmp FROM myTable;


Еще вопрос. Нужно ли делать индексы по полям больших временных таблиц для ускорения последующих запросов?
SELECT ... INTO - это создание новой таблицы с заполнением данными, а не INSERT в существующую.

Тогда видимо не понял) А в чем разница? Мне нужно просто чтобы было быстрее...
8 дек 16, 10:55    [19979368]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
WarAnt
Member

Откуда: Питер
Сообщений: 2423
Badhabit,

declare @table table - это табличная переменная, используйте ее когда у вас мало данных или например нужно чтоб данные сохранились даже после роллбека
table create #table - это временная таблица, используйте её когда нужно перелопачивать большие объемы данных, нужны полноценная статистика и нормально прикручиваемые индексы или например нужно передавать табличку из процедуры в процедуру.
8 дек 16, 10:56    [19979372]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
Badhabit
Member

Откуда:
Сообщений: 90
WarAnt
Badhabit,

declare @table table - это табличная переменная, используйте ее когда у вас мало данных или например нужно чтоб данные сохранились даже после роллбека
table create #table - это временная таблица, используйте её когда нужно перелопачивать большие объемы данных, нужны полноценная статистика и нормально прикручиваемые индексы или например нужно передавать табличку из процедуры в процедуру.

Данных у меня очень много и после запроса они мне вообще не нужны так что надо писать так:
select *
into #MyTbl
from myTable

Правильно?
Еще два глупых вопроса:
1. Как потом из временной выбирать? Пишу
select * from #MyTbl

пишет ошибку: "there is already an object named #MyTbl in the database"
2. Для ускорения последующих запросов по временным таблица нужно ли делать по ним индексы?
8 дек 16, 11:05    [19979412]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8805
Badhabit,

1. Обманываете, не на этом запросе.
2. Надо - делайте, не надо - не делайте.
8 дек 16, 11:08    [19979435]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Badhabit
пишет ошибку: "there is already an object named #MyTbl in the database"
Это если SELECT INTO
8 дек 16, 11:12    [19979458]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
Badhabit
Member

Откуда:
Сообщений: 90
iap
Badhabit
пишет ошибку: "there is already an object named #MyTbl in the database"
Это если SELECT INTO

А понял, он выдает ошибку если написать так:
select fld1,fld2 into #zzz from aaa
select * from #zzz
А со * все работает...
Почему не подскажете?
8 дек 16, 11:16    [19979486]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Badhabit
iap
пропущено...
Это если SELECT INTO

А понял, он выдает ошибку если написать так:
select fld1,fld2 into #zzz from aaa
select * from #zzz
А со * все работает...
Почему не подскажете?
Ошибка потому, что #zzz уже есть, а SELECT ... INTO #zzz пытается создать эту таблицу ещё раз.
Я же вам уже написал об этом.

А вы документацию принципиально не читаете?
Ваши вопросы аналогичны вопросам про букварь.
8 дек 16, 11:21    [19979520]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1090
Дедушка
with это синтаксический сахар.
при выполнении вашего последнего селекта все участвующие в нём cte заменятся на их текст (будет куча вложенных подзапросов).
замена cte на явные временные таблицы в большинстве случаев приводит к увеличению производительности.

а есть ли какие рекомендации общие, когда пользовать cte, когда временные таблицы? (если рекурсия не нужна)
8 дек 16, 11:25    [19979553]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
Badhabit
Member

Откуда:
Сообщений: 90
iap
Badhabit
пропущено...

А понял, он выдает ошибку если написать так:
select fld1,fld2 into #zzz from aaa
select * from #zzz
А со * все работает...
Почему не подскажете?
Ошибка потому, что #zzz уже есть, а SELECT ... INTO #zzz пытается создать эту таблицу ещё раз.
Я же вам уже написал об этом.

А вы документацию принципиально не читаете?
Ваши вопросы аналогичны вопросам про букварь.

Как же он #zzz есть? Я же как понимаю сначала создаю временную таблицу #zzz запросом select fld1,fld2 into #zzz from aaa
ну а потом просто пытаюсь из созданной выбрать: select * from #zzz
Хоть убейте не пойму)) Я видел ваш ответ, но в силу своих умственных способностей не понял его... И где конкретно в документации искать ответ тоже не нашел хотя читал на мсдн про select и into)) Подскажите статью..
8 дек 16, 11:32    [19979591]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
invm
Member

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

От тупого перекладывания промежуточных результатов во временные таблицы быстрее не станет. Особенно, если таких промежуточных данных много. Потому что наполнение временных таблиц и построение на них индексов тоже требует ресурсов.

ЗЫ: Волшебного универсального способа сделать "чтобы было быстрее" не существует.
8 дек 16, 11:33    [19979600]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Badhabit
Как же он #zzz есть?
Об этом вам простодушно сообщает сервер.
Ваш скрипт ведь кроме вас и вашего сервера никто не видел...
Так что можно судить только по отрывочным косвенным данным, аки Эркюль Пуаро.
8 дек 16, 11:42    [19979668]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
Badhabit
Member

Откуда:
Сообщений: 90
invm
От тупого перекладывания промежуточных результатов во временные таблицы быстрее не станет. Особенно, если таких промежуточных данных много. Потому что наполнение временных таблиц и построение на них индексов тоже требует ресурсов.

Т.е. если я вас правильно понял самый быстрый вариант это с вложенными подзапросами? Ну или же использование with ввиду того что он просто в итоге "раскрывает" подзапросы в результирующем запросе?
invm
ЗЫ: Волшебного универсального способа сделать "чтобы было быстрее" не существует.

Понятно, про волшебный алгоритм никто не спрашивал. Спросил что быстрее # или with - выяснилось, что # (или нет?). Уже результат.
8 дек 16, 11:45    [19979692]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
invm
Member

Откуда: Москва
Сообщений: 9825
Badhabit
Т.е. если я вас правильно понял самый быстрый вариант это с вложенными подзапросами?
Самый быстрый вариант для конкретного запроса всегда свой. Универсального "ускорителя" нет.
8 дек 16, 11:54    [19979738]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
Badhabit,

автор
Спросил что быстрее # или with - выяснилось, что # (или нет?). Уже результат.

кто быстрее черепаха или гепард? а если в воде? а в полёте? а на марсе?
8 дек 16, 11:56    [19979749]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8805
Badhabit,

читайте документацию, экспериментируйте, анализируйте. Не развивайте у себя культ карго.
8 дек 16, 11:57    [19979753]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Badhabit
самый быстрый вариант это с вложенными подзапросами?
Если бы был самый быстрый вариант на все случаи, то только его и оставили бы, не находите?
8 дек 16, 12:00    [19979758]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
Badhabit
Member

Откуда:
Сообщений: 90
из трех последних ответов понял что нужно просто написать 2 вида запроса с # и with запустить и сравнить, правильно?)
8 дек 16, 12:02    [19979767]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
Badhabit
из трех последних ответов понял что нужно просто написать 2 вида запроса с # и with запустить и сравнить, правильно?)
благославляю
8 дек 16, 12:06    [19979792]     Ответить | Цитировать Сообщить модератору
 Re: временные таблицы как правильно делать?  [new]
Badhabit
Member

Откуда:
Сообщений: 90
iap
Badhabit
Как же он #zzz есть?
Об этом вам простодушно сообщает сервер.
Ваш скрипт ведь кроме вас и вашего сервера никто не видел...
Так что можно судить только по отрывочным косвенным данным, аки Эркюль Пуаро.

все понял) она от предыдущего запроса осталась)) сделал drop table #zzz перед select fld1 into #zzz - все заработало)
8 дек 16, 12:19    [19979870]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить