Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Новости сайта "Упражнения по SQL" (http://www.sql-ex.ru) 234


Новости сайта "Упражнения по SQL (http://www.sql-ex.ru)"

Выпуск 234 от 21 марта 2009 г.

Новым посетителям сайта

SQL Exercises Сайт посвящен изучению языка, с помощью которого осуществляется взаимодействие с реляционными (и не только) СУБД. Суть обучения состоит в выполнении заданий на написание запросов к учебным базам данных; при этом система контролирует правильность выполнения заданий. В настоящее время реализованы все операторы подъязыка манипуляции данными (DML), которые включают в себя оператор извлечения данных SELECT, а также операторы модификации данных - INSERT, DELETE и UPDATE.

Мы надеемся, что справочного материала сайта окажется достаточно для самостоятельного обучения. Кроме того, свои решения вы можете обсудить на форуме сайта. Опытных же специалистов приглашаем проверить (продемонстрировать) свое мастерство и принять участие в соревновании, обеспечиваемом рейтинговой системой учета времени выполнения заданий. Фактически, рейтинг ведется на втором этапе тестирования, который начинается сейчас после решения 50-й задачи первого этапа. При подсчете рейтинга каждого участника отбрасывается один самый худший показатель среди всех решенных им упражнений.

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

Имеется возможность получить сертификат по SQL DML при выполнении определенного количества заданий.


Новости сайта

§ Ростовчан приглашаем посетить семинар, посвященный SQL Server 2008 Express.
Два доклада сделает Алексей Шуленин (Майкрософт):
1. Express - бесплатная редакция SQL Server. Обзор возможностей.
2. Подготовка отчетов с помощью SQL Server.
Семинар состоится 25 марта (начало в 15:40) по адресу:
ул. Мильчакова 10 (здание НКТБ Пьезоприбор), Факультет высоких технологий ЮФУ, а. 514 (5 этаж)

§ Новая задача от anddros выставлена на третьем этапе под номером 154 (сложность 4 балла).

§ Изменения среди лидеров (решенные за неделю задачи третьего этапа):
Смена лидера!
1. vlksm (154)
9. anddros (154)
34. AKudrakov (146)
45. SCAT (139)

§ Продвинулись в рейтинге:
51. B o r i s (136, 195.708)

§ Продвижение ближайших претендентов на попадание в ТОР 100:
144. -=ac=- (115, 61.146)
159. Lohmatyi (115, 2.189 )

§ На этой неделе сертифицированы:
Elz (B09040429) [AR] - г.Москва, Россия
Log1c (A09027850) [BK] - г.Харьков, Украина
Trotil (A09037915) [BK] - г.Москва, Россия

§ Число подписчиков - 3830

Число участников рейтинга - 19592

Число участников второго этапа - 1747

Число участников третьего этапа - 47

Сертифицировано на сайте - 359

Лучшие результаты (ТОР 20)

No Person Number of
Sel_ex
Last_Sel Number of
DML_ex
Scores Days Days_2 Days_3 S_3 LastSolved LastVisit
1 >Карасёва Н.В. (vlksm)1 154 154 21 376 1049 90.124 61.061 53 20 Mar 2009 20 Mar 2009
2 Креславский О.М. (Arcan)1 153 153 21 372 763 62.969 44.093 49 03 Mar 2009 20 Mar 2009
3 Сальников С.А. ($erges)1 152 152 21 369 356 3.781 4.118 46 16 Feb 2009 20 Mar 2009
4 Сенкевич С.В. (GreyC)1 152 152 21 369 358 57.860 27.102 46 26 Jan 2009 20 Mar 2009
5 Селезнёв А.С. (Артём С.)1 150 152 21 363 444 47.248 37.524 46 25 Jan 2009 03 Mar 2009
6 Никотин В.М. (@Nikotin)1 150 150 21 363 108 8.371 3.751 40 13 Dec 2008 20 Mar 2009
7 Зотов П.Г. (Ozzy)7 145 153 21 349 363 117.377 135.092 39 08 Mar 2009 20 Mar 2009
8 Печатнов В.В. (pvv)1 146 149 21 350 357 30.849 17.490 36 10 Oct 2008 20 Mar 2009
9 Дроздков А.Н. (anddros)9 148 154 21 358 295 6.074 6.723 35 18 Mar 2009 20 Mar 2009
10 Муллаханов Р.Х. (rem)9 149 152 21 358 483 14.427 20.056 35 05 Jan 2009 18 Mar 2009
11 Умрихина Е.В. (Umrikhina)10 148 148 21 356 316 18.299 20.658 33 06 Mar 2009 20 Mar 2009
12 Мурашкин И.В. (lepton)1 143 152 21 343 1059 68.477 57.992 33 14 Feb 2009 15 Feb 2009
13 Шиндин А.В. (AlShin)10 147 150 21 353 79 20.458 7.203 30 05 Jan 2009 28 Jan 2009
14 Держальцев В.А. (MadVet)7 137 146 21 331 1257 60.783 28.482 28 24 Sep 2008 30 Dec 2008
15 Любченко В.А. (IAS56)6 136 146 21 330 615 403.343 373.617 28 11 May 2008 01 Dec 2008
16 Голубин Р.С. (Roman S. Golubin)3 141 145 21 336 1260 93.162 58.822 25 29 Jan 2009 08 Feb 2009
17 Nikolaenko A.V. (Shadow77)12 142 147 21 337 436 77.451 14.010 23 22 Oct 2008 11 Dec 2008
18 Солдатенков Ю.С. (SolYUtor)2 138 146 21 329 819 22.615 6.102 20 14 Aug 2008 18 Mar 2009
19 Белогурова К. (Katy_Ekb)19 133 143 21 319 552 10.666 4.673 18 27 Nov 2008 18 Jan 2009
20 Егоров А.Б. (ABEgorov)20 137 144 21 327 180 12.897 8.815 18 03 Aug 2008 12 Aug 2008

Лучшие результаты за неделю

No surname n_sel sel_all sel_scores dml_scores scores rating last_visit
1 >b S.V. (skynet) 67 67 122 19 141 841 20 Mar 2009
2 Осадчий В.В. (Mathematician) 42 55 85 34 119 943 20 Mar 2009
3 >Мелентьев И.А. (Trotil) 29 71 56 34 90 504 20 Mar 2009
4 >Мартынюк (Wiedzmen) 35 85 68 19 87 331 20 Mar 2009
5 vsl V.V. (vsl) 36 36 67 6 73 2845 20 Mar 2009
6 >Егоров К. (KEg256) 29 40 63 0 63 2705 20 Mar 2009
7 >Баткаев Р. (yorcky) 15 59 23 34 57 858 20 Mar 2009
8 >Vashkervich N.I. (Natasha_Vashkevich) 12 48 22 34 56 1086 20 Mar 2009
9 >kozlov P.N. (kozlovpavel) 28 28 54 0 54 4410 20 Mar 2009
10 Nasibullina G.N. (guzka) 23 23 54 0 54 4413 19 Mar 2009
11 >Пустохайлов А.А. (Pustohaylov) 14 59 20 31 51 863 20 Mar 2009
12 Anosov Y.V. (Anosov) 22 46 50 0 50 2112 19 Mar 2009
13 Ильин (Nike6) 23 42 49 0 49 2439 20 Mar 2009
14 Кашин А.А. (akashin) 26 26 46 3 49 5004 20 Mar 2009
15 >Симакин В.А. (Rybak) 20 88 44 3 47 470 20 Mar 2009
16 Валеев М.А. (mksv) 21 50 38 9 47 1601 20 Mar 2009
17 Андрей (and1) 26 26 47 0 47 5211 20 Mar 2009
18 >Nino N. (Nino Kiviladze) 28 28 46 0 46 5331 20 Mar 2009
19 >panina (gruzman) 25 25 44 0 44 5591 20 Mar 2009
20 Galieva D.R. (Dilyara) 17 31 40 0 40 4043 19 Mar 2009
21 >Cherbikov P. (p_chernikov) 22 22 40 0 40 6063 20 Mar 2009

Изучаем SQL

Массивы и списки в SQL Server 2005 (начало в вып.217-229, 231-233)

Erland Sommarskog (оригинал: Arrays and Lists in SQL Server 2005 )
Перевод: Моисеенко С.И.

Передача чисел в двоичном виде

Метод элементов списка фиксированной длины представляет собой еще один метод для передачи списка чисел, если представить его в виде бинарной строки:

списка чисел, если представить его в виде бинарной строки:
CREATE FUNCTION fixbinary_single(@str varbinary(MAX))
RETURNS TABLE AS
RETURN(SELECT listpos = n.Number,
              n = convert(int, substring(@str, 4 * (n.Number - 1) + 1, 4))
       FROM   Numbers n
       WHERE  n.Number <= datalength(@str) / 4 )

(Должен ли я добавить, что эта идея также принадлежала Стиву Кассу?) При вызове из T-SQL она выглядит менее привлекательной:

CREATE PROCEDURE get_product_names_binary @ids varbinary(2000) AS
   SELECT P.ProductID, P.ProductName
   FROM   Northwind..Products P
   JOIN   fixbinary_single(@ids) b ON P.ProductID = b.n
go
EXEC get_product_names_binary 0x00000090000000C0000001B00000025

В моих тестах производительность fixbinary_single и fixstring_single была фактически идентичной. Однако, Алекс Кузнецов (Alex Kuznetsov), который прислал мне подобное предложение, указал, что таким способом Вы экономите на пропускной способности сети - аспект, который мной не тестировался. Вместо передачи 10 байтов на число, поскольку нам требуется строка, которая соответствовала бы всем положительным целым числам, бинарные строки требуют только четыре байта на число. Это может оказаться существенным выигрышем для длинных списков. Чтобы использовать эту возможность, Вы должны в коде клиента преобразовать ваши целые числа в массив байтов. Алекс любезно предоставил мне функцию C#, которая делает это для типа данных bigint.

static byte[] UlongsToBytes(ulong[] ulongs) {
   int ifrom = ulongs.GetLowerBound(0);
   int ito   = ulongs.GetUpperBound(0);
   int l = (ito - ifrom + 1)*8;
   byte[] ret = new byte[l];
   int retind = 0;
   for(int i=ifrom; i<=ito; i++)
   {
           ulong v = ulongs[i];
           ret[retind++] = (byte) (v >> 0x38);
           ret[retind++] = (byte) (v >> 0x30);
           ret[retind++] = (byte) (v >> 40);
           ret[retind++] = (byte) (v >> 0x20);
           ret[retind++] = (byte) (v >> 0x18);
           ret[retind++] = (byte) (v >> 0x10);
           ret[retind++] = (byte) (v >> 8);
           ret[retind++] = (byte) v;
   }

   return ret;
}

Заметим, что fixbinary_single не использует параметр @itemlen, который здесь оказывается лишним. Для обработки чисел других целочисленных типов потребуется отдельная функция.

Конечно, fixbinary_multi легко написать, но я оставлю это в качестве упражнения для читателя.

Фиксированная длина и CLR

Поскольку спецификой этого метода является формат входного параметра, а не сам алгоритм, Вы могли бы использовать для форматирования функцию CLR. Я написал табличнозначную функцию CLR, которая использует на входе элементы фиксированной длины. Было отмечено незначительное различие в производительности по сравнению с другими функциям CLR.

Производительность в случае очень длинного входного параметра

В начале этого раздела я говорил, что метод фиксированной длины является самым быстрым методом, за исключением случая очень длинного входа. Мои тесты на одной машине показали, что метод на основе фиксированной длины отстал от нескольких других методов, когда на вход подавался список из 10 000 строк. Это озадачивало меня в течение долгого времени, пока я как-то не запустил некоторые специальные тесты. Я пришел к заключению, что SQL Server имеет особенность в обработке nvarchar (MAX), которая проявляется в замедлении обработки, наступающей выше определенного предела. Этот предел - приблизительно 500 000 байтов на машинах x64, и 750 000 байтов на 32-разрядных машинах. (Я не имею доступа к какой-нибудь машине с архитектурой IA64, поэтому не могу оценить предельное значение для этого случая). Когда длина входа превышает этот предел, время выполнения функций фиксированной длины увеличивается примерно вдвое.

Я наблюдал эту проблему только в моих тестах с фиксированной длиной, поскольку только для фиксированной длины генерировались такие длинные входные строки. Однако и другие встраиваемые функции T-SQL, подобные inline_split_me, естественно, также подвержены этому явлению. С другой стороны, на процедуры, применяющие разбиение входной строки на куски, это оказывает влияние в меньшей степени, так как они выполняют меньше действий со строками большой длины. Проблема не возникает вообще, когда используются не SQL-методы: CLR обрабатывает длинные строки в .Net Framework, а XML также имеет собственный внутренний обработчик.

Я более подробно обсуждаю этот предел в приложении, посвященном производительности.

Альтернативный метод заполнить таблицу Numbers

Запрос, который я приводил в качестве примера заполнения таблицы Numbers, достаточно прост для понимания, но не очень эффективен. Поскольку вам предстоит это сделать всего один раз, производительность не является большой проблемой. Тем не менее, приведу блестяще быстрый запрос, который я заимствовал из книги Ицика Бена-Гaн (Itzik Ben-Gan) Inside SQL Server 2005: T-SQL Programming (SQL Server 2005 изнутри: Программирование в T-SQL):

CREATE FUNCTION dbo.fn_nums(@n AS bigint) RETURNS TABLE AS
RETURN
  WITH
  L0   AS(SELECT 1 AS c UNION ALL SELECT 1),
  L1   AS(SELECT 1 AS c FROM L0 AS A, L0 AS B),
  L2   AS(SELECT 1 AS c FROM L1 AS A, L1 AS B),
  L3   AS(SELECT 1 AS c FROM L2 AS A, L2 AS B),
  L4   AS(SELECT 1 AS c FROM L3 AS A, L3 AS B),
  L5   AS(SELECT 1 AS c FROM L4 AS A, L4 AS B),
  Nums AS(SELECT ROW_NUMBER() OVER(ORDER BY c) AS n FROM L5)
  SELECT n FROM Nums WHERE n <= @n;
GO
INSERT Numbers(Number) SELECT fn_nums(1000000)

Если, как предполагает Ицик, создание таблиц не находится в пределах ваших полномочий, Вы можете использовать функцию непосредственно в вашем запросе. Результаты тестов показали, что чем больше вам нужно чисел, тем больше затраты, связанные с этой функцией. Для функции типа chunk_split_me, которая никогда не требует более 8000 чисел, вообще не было замечено никакого существенного различия. Для fixstring_single, которая для 10 000 30-символьных элементов требует 300 000 чисел, падение производительности составило 25 %, что представляется удивительно низким. Есть риск при использовании этой встраиваемой функции с методом, который является также встраиваемым: когда я запускал тест с fixstring_single на SQL 2008, выполняя соединение с некластерным индексом моей тестовой таблицы, оптимизатор полностью потерялся и привел к плану, который выполнялся несколько минут всего лишь с 20 элементами в списке. На 2005 SQL я получил нормальный и быстрый план, но следует иметь в виду, что для вашего вопроса, это может оказаться и не так.

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

(Продолжение следует...)

Полезная информация

§ Приглашаем вас посетить новый проект - Интерактивный учебник по SQL.
   Ресурс позиционируется как "справочное обеспечение" для сайта SQL-EX.RU, но может использоваться и независимо от него.

§ Онлайновый выпуск рассылки можно почитать на сайте.

§ Все статьи, публикуемые в рассылке, затем выкладываются на сайте Книги и статьи по SQL.

§ Хотите поддержать проект? Вот инструкция по применению. :-)

Контакты

По всем вопросам, связанным с функционированием сайта, проблемами при решении упражнений, идеями вы можете обращаться к Сергею И.Моисеенко msi77[@]yandex.ru. Вы также можете предложить свои задачи для публикации на сайте.

Подписка Subscribe.Ru
Новости сайта "Упражнения по SQL"

В избранное