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

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


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

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

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

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

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

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


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

§ Автор - _Bkmz_ - усилил проверку задачи 89, добавив данные.

§ Новые лица в ТОР 100 и вернувшиеся туда:
47. Ozzy (задач 133, время 22.037)
98. aprog (122, 35.560)
99. Vetaleg (123, 46.812)

§ Продвинулись в рейтинге:
33. AKudrakov (135, 36.081)
35. Sysa (задач 134, время 77.723)
38. modicus (135, 8.658)
41. DeadLock5 (133, 124.014)
45. nebiros (134, 94.214)
54. TomGolab (132, 43.500)
58. Ocean (131, 40.319)
71. Fomichev (129, 14.160)
79. Чумазик (126, 94.952)
83. Eka (126, 10.901)
89. lexaNRJ (125, 81.621)

§ Продвижение ближайших претендентов на попадание в ТОР 100:
104. Чих (122, 36.857)
124. LexusSaD (119, 2.702)
132. _Bkmz_ (117, 2.558)
147. loki (110, 12.936)
163. HandKot_ (111, 160.222)
165. anddros (110, 1.561)

§ На этой неделе сертифицированы:
Ozzy (B08030213) [AR]) - г.Балашиха, МО, Россия
Alexey1515 (A08031102) [BK] - п.Топар, Казахстан
Nariman Kurbanoff (A08032727) [BK] - г.Ашгабат, Туркменистан
rangas (A08020871) [BK] - г.Верхняя Пышма, Россия

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

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

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

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

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

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

No Person Number of
Sel_ex
Last_Sel Number of
DML_ex
Scores Days Days_2 Days_3 S_3 LastSolved LastVisit
1 Сальников С.А. ($erges) 147 147 21 357 118 2.842 3.359 31 23 Jun 2008 28 Jun 2008
2 Карасёва Н.В. (vlksm) 147 147 21 357 778 73.340 46.383 31 22 Jun 2008 28 Jun 2008
3 Печатнов В.В. (pvv) 142 146 21 346 248 19.151 6.326 28 23 Jun 2008 27 Jun 2008
4 Креславский О.М. (Arcan) 143 146 21 348 510 22.488 12.553 28 23 Jun 2008 28 Jun 2008
5 Держальцев В.А. (MadVet) 142 146 21 347 1128 60.815 28.482 28 18 May 2008 23 Jun 2008
6 Любченко В.А. (IAS56) 142 146 21 347 615 403.439 373.617 28 11 May 2008 08 Jun 2008
7 Голубин Р.С. (Roman S. Golubin) 144 74 21 348 1044 92.981 58.822 25 27 Jun 2008 28 Jun 2008
8 Мурашкин И.В. (lepton) 139 146 21 338 767 37.107 26.815 21 28 Apr 2008 12 May 2008
9 Белогурова К. (Katy_Ekb) 138 143 21 335 361 10.714 4.673 18 20 May 2008 27 May 2008
10 Войнов П.Е. (pаparome) 143 146 21 343 1034 3.103 .213 17 23 Jun 2008 27 Jun 2008
11 Северюхин Ю.А. (Venser) 134 142 21 326 335 4.925 .655 14 01 Feb 2008 04 Feb 2008
12 Борисенков Д.В. (xuser) 137 142 21 331 92 3.217 .926 14 02 May 2008 30 May 2008
13 Мишин С.А. (CepbIu) 140 55 21 335 69 9.772 2.148 14 26 Jun 2008 27 Jun 2008
14 Тарасов Д.Б. (Gavrila) 137 142 21 330 998 23.531 2.501 14 20 May 2008 11 Jun 2008
15 Солдатенков Ю.С. (SolYUtor) 135 142 21 327 703 17.844 2.695 14 20 Apr 2008 26 Jun 2008
16 Кувалкин К.С. (Cyrilus) 135 142 21 327 1207 13.037 2.782 14 15 Mar 2008 28 Jun 2008
17 Шептунов П.П. (Dzen) 133 142 21 325 279 8.120 3.499 14 02 Oct 2007 15 Nov 2007
18 Селезнёв А.С. (Артём С.) 136 142 21 330 127 15.589 4.279 14 14 Mar 2008 31 Mar 2008
19 iglbeat (iglbeat) 140 55 21 335 318 27.448 6.641 14 27 Jun 2008 27 Jun 2008
20 Мальцев А.В. (Палкин) 133 142 21 325 422 48.779 7.690 14 13 Oct 2007 18 Jun 2008

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

No surname n_sel sel_all sel_scores dml_scores scores rating last_visit
1 Vildanov M. (mar_vi) 68 68 127 34 161 510 28 Jun 2008
2 Potasinski P. (brejk) 42 49 84 3 87 1710 27 Jun 2008
3 Ostrovskiy A.Б. (Stalex) 40 40 76 1 77 2384 27 Jun 2008
4 Пелеш Я.В. (Tokolist) 30 30 53 19 72 2630 27 Jun 2008
5 Зайцев В. (VSZ) 12 55 21 34 55 806 27 Jun 2008
6 123 (123) 22 34 51 0 51 3113 26 Jun 2008
7 Бедрин В.М. (BedrinVas) 22 26 42 9 51 3785 25 Jun 2008
8 Istrashkin B. (raggzy11) 24 44 50 0 50 2267 28 Jun 2008
9 >Царьков А.Г. (Skypchel) 14 42 26 19 45 1611 28 Jun 2008
10 Субботин С.Г. (SGS) 20 31 45 0 45 3656 27 Jun 2008
11 Навознов И.Е. (beat) 25 25 45 0 45 4781 26 Jun 2008
12 Krasilnikov D.E. (KDE) 24 24 43 0 43 5100 27 Jun 2008
13 >ivanov (dyp) 7 59 11 31 42 742 28 Jun 2008
14 Калинин А.П. (Андрябро) 19 40 42 0 42 2563 27 Jun 2008
15 Сизов Д.С. (D-m-i-t-r-y) 16 67 28 11 39 585 27 Jun 2008
16 Sadoviy T. (Tarass) 21 21 38 0 38 5541 26 Jun 2008
17 Соколов А. (Falcon06) 17 64 29 8 37 811 28 Jun 2008
18 Киняпин С.В. (sergeykin2008) 14 26 35 0 35 4509 27 Jun 2008
19 Малафеев А.В. (North Alex) 16 26 33 0 33 4959 27 Jun 2008
20 >Васьковский С.А. (vaskovskiy) 20 20 32 0 32 6371 28 Jun 2008
21 Dziubek M. (MDziubek) 20 20 31 0 31 6528 26 Jun 2008
22 Поволоцкий (Кrizai) 21 21 31 0 31 6544 27 Jun 2008
23 Dmytruk V.V. (Coris) 20 20 28 3 31 6550 27 Jun 2008
24 TT T. (redmonkey) 20 20 31 0 31 6555 27 Jun 2008
25 Куринной А.А. (Алексаныч) 12 34 30 0 30 2984 27 Jun 2008

Изучаем SQL

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

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

Раздел 1: Предпосылки. Недостающие элементы в стандартном SQL до введения в него предложения OVER

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

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

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

SQL требует совершенно другого типа мышления. Существуют определенные типы решений в SQL Server 2000, которые интуитивно не понятны и требуют нестандарного мышления. Вот некоторые примеры: ранжирование или агрегирование данных, являющихся логическим подмножеством результирующих данных; вычисление нарастающих итогов, скользящих или на данный год; отображение атрибутов базовой строки и агрегатов для той же строки; сравнение строк и т.д.

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

Договоримся, что мы принимаем стиль мышления SQL и попытаемся решить задачу в рамках теоретико-множественного подхода на SQL Server 2005 с помощью коррелирующего подзапроса.

(Прим. перев.: база данных Northwind для SQL 2000)

-- Агрегаты с накоплением
--Создаем таблицу EmpOrders в базе данных tempdb, используя данные из Northwind
-------------------------------------------------------------------------------
USE tempdb;

IF OBJECT_ID('EmpOrders') IS NOT NULL
  DROP TABLE EmpOrders
GO

CREATE TABLE EmpOrders
(
  empid      INT      NOT NULL,
  ordermonth DATETIME NOT NULL,
  qty        INT      NOT NULL,
  PRIMARY KEY(empid, ordermonth)
)

INSERT INTO EmpOrders(empid, ordermonth, qty)
  SELECT O.EmployeeID,
    CAST(CONVERT(CHAR(6), O.OrderDate, 112) + '01' AS DATETIME) AS ordermonth,
    SUM(Quantity) AS qty
  FROM Northwind.dbo.Orders AS O
    JOIN Northwind.dbo.[Order Details] AS OD
      ON O.OrderID = OD.OrderID
  GROUP BY EmployeeID,
    CAST(CONVERT(CHAR(6), O.OrderDate, 112) + '01' AS DATETIME);

SELECT empid, CONVERT(CHAR(10), ordermonth, 121) AS ordermonth, qty
FROM EmpOrders
ORDER BY empid, ordermonth;

-----------------------------------------------------------------------------
-- Агрегаты с накоплением
-- Решение 1 : Использование коррелирующих подзапросов
-----------------------------------------------------------------------------
SELECT O1.empid, O1.ordermonth, O1.qty,
  (SELECT SUM(O2.qty)
   FROM EmpOrders AS O2
   WHERE O2.empid = O1.empid
     AND O2.ordermonth <= O1.ordermonth) AS cumulativeqty
FROM EmpOrders AS O1;

Первое, что мы увидим - способ организации запроса. Большинство людей, вероятно, подумали бы так: требуется вычислить нарастающий итог независимо для каждого работника на основании хронологического упорядочения месяцев в году. Но без возможности выполнить вычисления, основанные на упорядоченном наборе, мы должны принять образ мышления теории множеств и переформулировать запрос следующим образом: для каждой строки (назовем ее текущей строкой) вычислить общее количество по строкам, в которых работник тот же, что и работник в текущей строке, а месяц не больше, чем месяц в текущей строке.

Второе, что мы увидим, это то, что запрос этот очень неэффективный. Давайте проанализируем план его выполнения, представленный на рис. 1-1.


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

Во-первых, выполняется полное сканирование таблицы (Clustered Index Scan - сканирование кластерного индекса). Приняв за P число разбиений (работников), а за N - среднее количество строк для каждого разбиения в таблице, стоимость этого сканирования будет P*N. Для каждой строки, возвращаемой при сканировании таблицы, SQL Server выполняет Seek (поиск)+ Partial Scan (частичное сканирование) в кластерном индексе, созданном на столбцах (empid, ordermonth), для получения строк, для которых выполняется агрегирование (обозначено в плане как Clustered Index Seek). В целях дискуссии и для упрощения вычислений, ограничимся стоимостью набора частичных сканирований на листе и опустим все другие стоимости в этом плане. Число строк, сканированных на листе индекса на каждую внешнюю строку есть число строк, имеющих такое же значение empid, как во внешней строке, и не превышает ordermonth. В среднем оно равно (1+N) /2 строк для каждой внешней строки. В итоге число строк при частичных сканированиях можно оценить так: P*N* (1+N) /2 = P* (N+N^2) /2. Таким образом, алгоритмическая сложность этого плана равна N^2. При большом количестве строк на работника вы получаете просто огромные числа. Например, при 5 работниках и 100.000 строк на работника, вы получаете сканирование 25 000 250 000 строк. Оценка времени выполнения подобного запроса - более часа. С увеличением количества строк на работника падение производительности будет нелинейным - N^2. Например, для одного разбиения и 10 000 000 строк этот запрос исполнялся бы около года!

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

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

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

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

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

Контакты

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

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

В избранное