Главная страница  Карта сайта  Печать  Написать письмо  Twitter  RSS
Войти
Персональный сайт
Стеллецкого Владимира
Обновлено: 25.09.2018 г.

Примеры с SQL

« первая  ‹ предыдущая  1  2  3  4  5  следующая ›  последняя »

Кучи, кучи, кучи... (20.11.2016) #

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

-- все таблицы в базе без кластерного индекса (кучи)
select distinct top 1000
    s.name as [Schema],
    o.name as [TableName],
    ps.row_count as [RowCount]
from sys.objects o
    left join sys.schemas s
        on o.schema_id = s.schema_id
    inner join sys.indexes i
        on o.object_id = i.object_id
    inner join sys.dm_db_partition_stats ps
        on o.object_id = ps.object_id
where
    o.type_desc = 'USER_TABLE' and
    i.type_desc = 'HEAP'
order by
    [RowCount] desc

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

Грабли при написании SQL-запросов для MS SQL-сервера. (15.11.2016) #

Прочитал интересную статью со сборником частых ошибок, которые допускают при написании SQL-запросов.

Для себя могу отметить следующее (далее пункты соответствуют пунктам в статье):

  1. Правильность типа данных очень важна.
  2. SELECT * - зло!
  3. Alias нужны всегда и для всех объектов.
  4. Нельзя ориентироваться на порядок колонок в таблице.
  5. Коварный NULL (его необходимо учитывать при сравнениях).
  6. Константы даты только YYYYMMDD (раньше писал с дефисами, больше не буду).
  7. Интересные решения по фильтрации по дате - вычисляемое поле и индекс.
  8. Нельзя преобразовывать колонки в WHERE.
  9. Всегда необходимо указывать правильный тип констант (строки в кавычках).
  10. Для поиска с начала только LIKE.
  11. Для констант в UNICODE всегда N (иначе будет приведение к ANSI).
  12. COLLATE очень важен.
  13. Для LIKE c %Value% можно использовать BINARY COLLATE.
  14. Имена всех объектов писать строго как в БД (иначе м.б. проблемы с COLLATE).
  15. Внимание с CHAR и VARCHAR (т.к. есть отличия в сравнении по LIKE).
  16. Важно указывать размерность типа (просто VARCHAR = VARCHAR(1), но в CAST/CONVERT будет VARCHAR(30)).
  17. ISNULL и COALESCE (первый приводит к меньшему типу, второй к большему, но работает медленнее).
  18. Внимательнее с математическими операциями - результат зависит от типов операндов.
  19. UNION vs UNION ALL (первый медленно, но может выполняться параллельно, второй быстро но последовательно).
  20. Внимательнее с подзапросами в SELECT - могут быть лишние чтения.
  21. В подзапросах может вернуться более одного результата (тогда ошибка).
  22. CASE WHEN - может привести многократному вычислению одних и тех же операторов.
  23. Scalar func - зло (особенно с параметрами и вычислениями).
  24. Внимательнее с VIEWs (могут быть проблемы с производительностью, если нужны не все колонки).
  25. CURSORs - зло (только если по-другому нельзя).
  26. Пока нет STRING_CONCAT - XML оптимальный вариант (90% случаев).
  27. SQL Injection - использовать sp_executesql с параметрами, вместо ручной склейки строки.

PS: Для отображение численных характеристик выполнения запроса можно использовать SET STATISTICS TIME, IO ON перед запросом и OFF после.

Комментарии

swi, www (20.11.2016)
Спасибо. Очень интересно!
Мне тоже статья понравилась (даже не поленился сделать себе конспект).

Microsoft SQL Server 2016 (20.10.2016) #

В понедельник на работе перешли на Microsoft SQL Server 2016. Учитывая, что переходили с довольно таки старого 2008, постарались подготовиться получше. Переход прошёл в целом очень хорошо, но всё же некоторые непредвиденные сложности возникли:

  • Несколько запросов перестало выполняться из-за использования некорректных типов данных.
  • Некоторые сложности возникли с правами для прилинкованного сервера. Сам сервер прилинковался "на ура", но вот запросы с него не выполнялись, выдавая следующую ошибку: Причём, у привилегированного пользователя всё работало, а у обычного нет. Но стоило выполнить запрос под привилегированным пользователем, как начинало работать и под обычным, правда, не долго - через какое-то время снова выдавало ошибку. По тексту ошибки и нескольким статьям в интернете предположили, что проблема в том, что "обычным" пользователям прилинкованный сервер не отдавал статистику, а без этого запросы не выполнялись.

Повреждение данных в SQL Server 2012 и 2014 при перестроении индексов в режиме online (17.09.2016) #

Коллега по работе прислал ссылку на интересную, а главное крайне полезную статью.
Кратко: без установленного исправления KB #2969896 в SQL Server 2012 и 2014 при перестроении индексов в режиме online может произойти повреждение индексов и даже потеря данных в таблице.

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

Полезные ссылки (27.03.2016) #

Текущий пользователь (18.11.2014) #

Иногда на прямо на SQL-сервере бывает необходимо узнать от имени какого пользователя выполняется тот или иной запрос. В этом случае на выручку приходит функция:

print SYSTEM_USER -- Пользователь, под которым подключились к базе данных

Чаще всего я использую данную функцию как временное (отладочное) решение, когда необходимо определить какой пользователь создал или изменил запись в таблице. Для этого достаточно в таблицу добавить поле (NOT NULL) и указать для него в качестве значения по умолчанию SYSTEM_USER.

UPD: Появилось только 2005 MSSQL (было исправлено после уточнения в комментариях)

Комментарии

Denis Wilson (17.11.2014)
В сообщении пару неточностей - этим способом нельзя узнать, какой пользователь изменил запись в таблице, если в запросе UPDATE явно не указано обновление поля значением SYSTEM_USER - инструкция UPDATE изменяет только те поля, которые там указаны, а пользователь останется прежним. Этот метод работает только для INSERT. А сама функция появилась в MS Sql Server 2005.
Спасибо за уточнение.
Для контроля изменения записей использую триггеры, из-за чего получилась некоторая неоднозначность в тексте сообщения.
Версию MS SQL в исходном сообщении исправил.

Ошибка в возвращаемом значении SCOPE_IDENTITY() и @@IDENTITY (18.02.2015) #

We've caught both SCOPE_IDENTITY() and @@IDENTITY returning the incorrect value after doing an insert. It appears to be some combination of our database settings, the number of rows in the tables, and the particulars of the query plan.

https://connect.microsoft.com/SQLServer/feedback/details/328811/scope-identity-sometimes-returns-incorrect-value

То есть в 2008 SQL-сервере SCOPE_IDENTITY() (а также @@IDENTITY) иногда может и "пошутить" - вернуть некорректное значение. Ошибка проявляется при некоторых настройках базы, и определенном кол-ве записей в таблице (>1000000). Вроде как устранено в пакете обновления SP3.

« первая  ‹ предыдущая  1  2  3  4  5  следующая ›  последняя »

  Вы 44841 посетитель этой странички
с 07 октября 2006 года
© http://svv-home.ru
О сайте