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

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


Новости сайта "Упражнения по SQL (http://www.sql-ex.ru)" Выпуск 198 (12 июля 2008 г.)

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

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

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

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

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


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

§ Хоть и незначительные расхождения в схемах и данных баз, используемых для решения задач на SELECT и DML, все же имеют место. Это вызывало справедливые замечания.
Я подготовил скрипты доступных баз данных, используемых для решения задач по DML, которые можно скачать по ссылкам:
Компьютеры
Корабли

§ Исправил баг с удвоением кавычек, который имел место при редактировании сообщений на форуме.

§ Добавил на страницу результатов голосования по задачам всплывающие подсказки с краткими формулировками задач.

§ Переработал описания учебных баз данных с учетом накопивших замечаний.

§ Очередное добавление данных от _Bkmz_ усилило проверку задачи 89.
Проверьте свои решения.

§ С результатом (задач 138, время 23.307) подошел к третьему этапу Shadow77.
Одна задача до третьего этапа осталась Angellore (задач 137, время 93.070).

§ Изменения среди лидеров (решенные за неделю задачи третьего этапа):
32. Shadow (139)

§ Новые лица в ТОР 100 и вернувшиеся туда:
57. anddros (130, 2.351)
79. _Bkmz_ (127, 3.408)

§ Продвинулись в рейтинге:
36. DeadLock5 (137, 132.202)
38. ivan.korobov (136, 90.193)
45. TomGolab (135, 47.421)
46. Scorpion (135, 65.144)
50. marishkin (130, 23.984)
53. Fomichev (132,14.497)
55. Heromantor (131, 9.982)
65. raul (131, 17.825)
69. Чумазик (129, 123.824)

§ Продвижение ближайших претендентов на попадание в ТОР 100:
122. Rash ST (120, 7.346)
125. Sergey79 (118, 262.403)
134. HandKot_ (118, 169.493)
154. shadon (113, 15.156)
168. Umrikhina (110, 1.795)

§ На этой неделе сертифицированы:
=marinos= (A08033862) [BK] - г.Тамбов, Россия
Красный барон (A08032322) [BK] - г.Новосибирск, Россия
Мари_Андреева (A08034143) [BK] - г.Москва, Россия
gruzdev_sergey (A08031608) [BK] - г.Алушта, Украина

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

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

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

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

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

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

NoPersonNumber of
Sel_ex
Last_SelNumber of
DML_ex
ScoresDaysDays_2Days_3S_3LastSolvedLastVisit
1Сальников С.А. ($erges)147147213571182.8423.3593123 Jun 2008 11 Jul 2008
2Креславский О.М. (Arcan)147892135751737.67127.4983130 Jun 2008 11 Jul 2008
3Карасёва Н.В. (vlksm)1471472135777873.34046.3833122 Jun 2008 10 Jul 2008
4Печатнов В.В. (pvv)146892135425719.4266.3262802 Jul 2008 11 Jul 2008
5Держальцев В.А. (MadVet)14214621347112860.81528.4822818 May 2008 23 Jun 2008
6Любченко В.А. (IAS56)14214621347615403.439373.6172811 May 2008 08 Jun 2008
7Голубин Р.С. (Roman S. Golubin)1447421348104492.98158.8222527 Jun 2008 11 Jul 2008
8Мурашкин И.В. (lepton)144892134783937.28926.8152109 Jul 2008 09 Jul 2008
9Белогурова К. (Katy_Ekb)1381432133536110.7144.6731820 May 2008 08 Jul 2008
10Войнов П.Е. (pаparome)1431462134310343.103.2131723 Jun 2008 11 Jul 2008
11Северюхин Ю.А. (Venser)134142213263354.925.6551401 Feb 2008 04 Feb 2008
12Борисенков Д.В. (xuser)13714221331923.217.9261402 May 2008 30 May 2008
13Мишин С.А. (CepbIu)1405521335699.7722.1481426 Jun 2008 04 Jul 2008
14Тарасов Д.Б. (Gavrila)1395521332104823.5542.5011409 Jul 2008 11 Jul 2008
15Солдатенков Ю.С. (SolYUtor)1351422132770317.8442.6951420 Apr 2008 11 Jul 2008
16Кувалкин К.С. (Cyrilus)13514221327120713.0372.7821415 Mar 2008 01 Jul 2008
17Шептунов П.П. (Dzen)133142213252798.1203.4991402 Oct 2007 15 Nov 2007
18Селезнёв А.С. (Артём С.)1361422133012715.5894.2791414 Mar 2008 31 Mar 2008
19iglbeat (iglbeat)141742133732827.4926.6411407 Jul 2008 11 Jul 2008
20Мальцев А.В. (Палкин)1331422132542248.7797.6901413 Oct 2007 18 Jun 2008

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

Nosurnamen_selsel_allsel_scoresdml_scoresscoresratinglast_visit
1>Пупкин В. (dark master)66661233415756511 Jul 2008
2Sizyh M.N. (MarSi)525298098159311 Jul 2008
3>Ochkin S. (Sergey Ochkin)414176076246011 Jul 2008
4>Новиков (Новиков)363666369282811 Jul 2008
5>Karpets (Fokus)294064367231611 Jul 2008
6>Sabara A.T. (Tohich)363667067292911 Jul 2008
7>Поляков А.Н. (Warri)363667067293211 Jul 2008
8>Shevyakov M. (Mikha)304165065243811 Jul 2008
9Цаплин С.В. (Allgood)284360262124711 Jul 2008
10>Хлусов П.В. (lamort1985)187035235857611 Jul 2008
11>Senyshyn A. (AirMan)313158058356411 Jul 2008
12blablabla C.G. (cpblnc)292956056372309 Jul 2008
13Марченко О.С. (olgas)254154054245907 Jul 2008
14Гулечко С.С. (Idaho)272748351419610 Jul 2008
15>Kiriluyk A.A. (SancheZZZ)282848048452811 Jul 2008
16>Synyuta Y.V. (Yura_Synyuta)262647047464511 Jul 2008
17Ogg (nanny)1111123446478411 Jul 2008
18>Романец М. (Deadok)1550261945109811 Jul 2008
19>Cherepanov D. (Simplex)194341445126311 Jul 2008
20Токмянина Т.И. (Chedi)193445045237710 Jul 2008
21Панков И.А. (kellagost)1919281745486011 Jul 2008
22Белик С.Н. (SerguS)252541041531207 Jul 2008
23Рябчук В.В. (Hous)232338240543510 Jul 2008
24>jain R. (rohit2910)242437340544611 Jul 2008

Изучаем SQL

Требования к SQL Server по усилению поддержки: предложение OVER() и упорядоченные вычисления (продолжение, начало в вып.195)

Itzik Ben-Gan и Sujata Mehta (оригинал: SQL Server Feature Enhancement Request - OVER Clause and Ordered Calculations )
Перевод Карасева Н.В.

----------------------------------------------------------
-- Агрегация с накоплением
-- Решение 3 : Использование курсоров
----------------------------------------------------------
USE tempdb;
GO

-- Cursor
DECLARE @aggtable TABLE(empid INT, Ordermonth DATETIME, qty INT, cumulativeqty INT, avgqty DECIMAL(12,2));
DECLARE @empid INT, @prevempid INT, @ordermonth DATETIME, @qty INT, @cntqty INT, @cumulativeqty INT, @avgqty DECIMAL(12,2);

DECLARE aggcursor CURSOR FAST_FORWARD FOR
  SELECT empid, ordermonth, qty
  FROM dbo.EmpOrders
  ORDER BY empid, ordermonth, qty;
OPEN aggcursor;

FETCH NEXT FROM aggcursor INTO @empid, @ordermonth, @qty;

SELECT @prevempid = @empid, @cntqty = 0, @cumulativeqty = 0, @avgqty = 0.0;

WHILE @@fetch_status = 0
BEGIN
  IF @empid <> @prevempid
 SELECT @prevempid = @empid, @cntqty = 0, @cumulativeqty = 0, @avgqty = 0.0;
  SET @cntqty = @cntqty + 1;
  SET @cumulativeqty = @cumulativeqty + @qty;
  SET @avgqty = 1.0 * @cumulativeqty/@cntqty;

  INSERT INTO @aggtable (empid, Ordermonth, qty, cumulativeqty, avgqty)
  VALUES (@empid, @ordermonth, @qty, @cumulativeqty, @avgqty);
  FETCH NEXT FROM aggcursor INTO @empid, @ordermonth, @qty;
END

CLOSE aggcursor;
DEALLOCATE aggcursor;

  SELECT empid, ordermonth, qty, cumulativeqty, avgqty
  FROM @aggtable
  ORDER BY empid, ordermonth, qty;
GO
--------------------------------------------------------------------------------

Рисунок 1-4: План выполнения для запроса, использующего курсор для вычисления множественных агрегатов с накоплением

Если мы посмотрим план исполнения на рисунке 1-4, то данные сканируются один раз; после этого используется построчный цикл обхода курсора для вычисления агрегатов. Однако код длинный и сложный, и обслуживание его обходится дорого. Производительность решения с курсором равна P*N*O, где добавка O связана с построчной обработкой, (напомним, что P - это число разбиений, N - количество строк на разбиение). Сказанное означает, что курсоры имеют линейное падение производительности. Так, если число строк N достаточно велико, то курсоры дают значительный выигрыш по сравнению с решениями на основе множеств. На рисунке 1-5 показаны сравнительные графики оценок производительности двух рассмотренных решений - с помощью курсоров и без них.

Рисунок 1-5: Агрегаты с накоплением: оценки производительности запроса, основанного на теории множеств, и запроса, использующего курсор

Следующим примером задач, где используется последовательность и где можно получить выигрыш за счет упорядоченных вычислений, является задача сравнения соседних строк. Здесь вам будет продемонстрирован очень простой пример, но заметим, что сравнение сосодних строк необходимо для многих задач бизнеса (например, вычисление трендов, поиск пропуска в последовательностях, отчеты о наличии, и так далее).

Давайте сравним значения в каком-нибудь столбце текущей строки со значениями для того же столбца в следующей строке таблицы (принимая некоторый порядок последовательности строк).

------------------------------------------------------------
-- Сравнение соседних строк
------------------------------------------------------------

IF OBJECT_ID('dbo.T1') IS NOT NULL
  DROP TABLE dbo.T1;
GO
CREATE TABLE dbo.T1(col1 INT NOT NULL PRIMARY KEY);
GO

INSERT INTO dbo.T1 VALUES(1);
INSERT INTO dbo.T1 VALUES(2);
INSERT INTO dbo.T1 VALUES(3);
INSERT INTO dbo.T1 VALUES(100);
INSERT INTO dbo.T1 VALUES(101);
INSERT INTO dbo.T1 VALUES(102);
INSERT INTO dbo.T1 VALUES(103);
INSERT INTO dbo.T1 VALUES(500);
INSERT INTO dbo.T1 VALUES(997);
INSERT INTO dbo.T1 VALUES(998);
INSERT INTO dbo.T1 VALUES(999);
INSERT INTO dbo.T1 VALUES(1000);
GO
SELECT * FROM T1
GO

Термины следующая или предыдущая строки характерны для курсоров, но не для наборов данных. Таких понятий не существуют для наборов данных. Поэтому мы должны "перевести" эти понятия в нечто, имеющее смысл для наборов данных, т.е.

следующий = минимум, больший чем текущее значение

предыдущий = максимум, меньший чем текущее значение

SELECT col1 AS cur,
  (SELECT MIN(col1) FROM dbo.T1 AS B
   WHERE B.col1 > A.col1) AS nxt
FROM dbo.T1 AS A;

Cur     nxt
1  2
2  3
3  100
100  101
101  102
102  103
103  500
500  997
997  998
998  999
999  1000
1000 NULL

Рисунок 1-6: План выполнения запроса для сравнения строк при теоретико-множественном подходе

Этот способ мышления не является интуитивно понятным и увеличивает сложность понимания. Но что более важно, если мы рассматрим план выполнения на рисунке 1-6, то мы увидим, что оптимизатор выполняет поиск в индексе для каждой строки; это говорит о том, что оптимизатор не учитывает порядок и просто повторяет поиск для каждой строки. Поэтому вместо того, чтобы один раз выполнить проход по упорядоченному набору данных в индексе, мы поднимаем стоимость запроса до N + N*S, где N - число строк в таблице, а S - стоимость операции поиска записи. Например, если мы имеем 1.000.000 строк в таблице размещенной на нескольких тысячах страниц, то стоимость операции составила бы 3.000.000 операций прямого чтения (при 3 уровнях в индексе). Это ещё упрощенный сценарий; в вычислениях тренда, задачах учета и т.д. вам необходим доступ к атрибутам соседней строки, которые не зависят от атрибута, определяющего порядок последовательности. В этих случаях все становится сложнее, что потребует использования TOP в подзапросах.

Итак, в этом разделе показаны некоторые "пропуски" или недостающие элементы в SQL (до введения конструкции OVER), из-за которых отсутствует эффективная поддержка таких типов распространенных задач как вычисление нарастающих агрегатных значений или сравнения соседних строк. Имеющиеся варианты длинны, сложны или интуитивно не очевидны, и мало эффективны. Теперь давайте перейдем к введению в SQL конструкции OVER, её неполной реализции в SQL Server 2005 и к некоторым элементам конструкции все ещё не реализованным в SQL Server.

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

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

§ Мы принимаем участие в конкурсе Ростовских сайтов. Голосовать можно один раз в день, если, конечно, есть желание :-).
Чтобы голосовать требуется авторизация.

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

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

§ Желающих поспособствовать популяризации сайта прошу проголосовать/поставить закладку в социальных сетях:
del.icio.us
dzone.com
Digg.com
stumbleupon.com

Контакты

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

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

В избранное