Що може прискорити запит підрахунку SQL?


9

Під час підрахунку (сукупності) SQL-запиту, що може пришвидшити час виконання цих трьох систем баз даних? Я впевнений, що багато речей можуть пришвидшити це (обладнання для одного), але я просто початківець DBA, тому я впевнений, що тут я отримаю кілька відповідей. Я перемістив близько 157 мільйонів рядків до бази даних SQL Server, і цей запит триває назавжди. Але в моїй базі даних Netezza потрібні секунди.

Наприклад:

Нетеца 6:

SELECT COUNT(*) FROM DATABASENAME..MYTABLE

Oracle 11g:

SELECT COUNT(*) FROM MYTABLE

SQL Server 2012:

SELECT COUNT(*) FROM DATABASENAME.[dbo].[MYTABLE]

Може подивитися на це питання: stackoverflow.com/questions/11130448/sql-count-performance

1
Чи потрібно це робити лише один раз або багаторазово?
Джон Сейгель

@JonSeigel ми робимо додаткові навантаження, і ми щодня порівнюємо записи між системами баз даних, щоб переконатися, що підрахунки підсумовуються. Так неодноразово.
MacGyver

Відповіді:


10

Netezza - це пристрій, розроблений для того, щоб досягти найкращих результатів сканування столу, тому ви отримуєте такі швидкі результати в цій системі.

Для вашого SQL-сервера ви можете значно пришвидшити кількість рядків шляхом запиту з DMV sys.dm_db_partition_stats.

SELECT s.name AS [Schema], o.name AS [Table], SUM(p.row_count) AS [RowCount]
FROM sys.dm_db_partition_stats p JOIN sys.objects o
ON p.object_id = o.object_id JOIN sys.schemas s
ON o.schema_id = s.schema_id
WHERE p.index_id < 2
AND o.object_id = object_id('MyTable')
GROUP BY o.name, s.name;

У високому середовищі транзакцій цей DMV не гарантується 100% точним. Але з вашого запитання здається, що ви просто робите підрахунок рядків для перевірки кожної таблиці після міграції, тому цей запит повинен працювати для вас.


4
@Phil чому? Якщо ви переходите через таблиці та виконайте дорогий SELECT COUNT (*) з кожної з них - наскільки точним є перший результат, коли ви дійшли до останньої таблиці?
Аарон Бертран

1
Для наочності Філ сказав: "Використання словника даних, який не дає 100% точних результатів, є поганою порадою. На мою думку, відповідь слід відредагувати, щоб видалити пропозицію, або видалити - пам'ятайте, люди в Google за такими відповідями і будуть сліпо вирізати та вставити ... "Я погоджуюся з тим, що відмова від відповідальності є важливою (і, мабуть, є деякі крайні випадки, коли метадані не повертають розумних результатів), я не погоджуюся, що використання поглядів метаданих взагалі є поганою порадою.
Аарон Бертран

5

Ось рішення SQL Server, яке використовує COUNT_BIGвсередині індексованого виду. Таким чином ви отримаєте послідовно підрахунок транзакцій без накладного сканування великої таблиці або індексу та без необхідності зберігання, необхідного для останнього:

CREATE TABLE [dbo].[MyTable](id int);
GO

CREATE VIEW [dbo].[MyTableRowCount]
    WITH SCHEMABINDING
AS

    SELECT
        COUNT_BIG(*) AS TableRowCount
        FROM [dbo].[MyTable];
GO

CREATE UNIQUE CLUSTERED INDEX IX_MyTableRowCount
    ON [dbo].[MyTableRowCount](TableRowCount);
GO

SELECT
    TableRowCount
    FROM [dbo].[MyTableRowCount] WITH(NOEXPAND);

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


@SQLKiwi: Як прочитані заблоковані до 2012 року? Помилка SQL Server?
Джон Сейгель

@JonSeigel - Мій 0,05 долара: Нормальні кластеризовані індекси для звичайної таблиці, створеної в автономному режимі, застосовують замок Sch-M на столі. Для подання, звичайно, це не потрібно, але це означає зміну операції Create Index для створення спеціального випадку для індексованого перегляду - що було зроблено для SQL2012. ІМХО, звичайно.
Fabricio Araujo

3

В Oracle, двійковий індекс дерева у стовпці NOT NULL може використовуватися для відповіді на COUNT (*). У більшості випадків це буде швидше, ніж ПОЛІТИЧНИЙ СКАН, тому що індекси зазвичай менші, ніж їх основна таблиця.

Однак звичайний бінарний індекс дерева все ще буде величезним з 157 Mrows. Якщо ваша таблиця не оновлюється одночасно (тобто лише процес завантаження пакетної версії), ви можете замість цього використовувати індекс растрових зображень.

Найменший растровий індекс буде приблизно таким:

CREATE BITMAP INDEX ix ON your_table(NULL);

Нульові записи враховуються індексом растрових зображень. Отриманий індекс буде невеликим (20-30 8 кб блоків на мільйон рядків) порівняно з звичайним бінарним індексом дерева або базовою таблицею.

Отриманий план повинен відображати такі операції:

----------------------------------------------
| Id  | Operation                     | Name | 
----------------------------------------------
|   0 | SELECT STATEMENT              |      |
|   1 |  SORT AGGREGATE               |      |
|   2 |   BITMAP CONVERSION COUNT     |      |
|   3 |    BITMAP INDEX FAST FULL SCAN| IX   |
----------------------------------------------

Якщо ваша таблиця оновлюється одночасно, індекс растрових зображень з унікальним значенням буде суперечкою і не повинен використовуватися.


3

В Oracle простий запит підрахунку часто виконується шляхом сканування індексу замість цілої таблиці. Індекс повинен бути індексом растрових зображень або визначеним у стовпці з обмеженням NOT NULL. Для більш складних запитів, які потребують повного сканування таблиці, можна використовувати паралельний запит.

Щоб увімкнути паралельний запит (потрібне видання Enterprise), ви можете використовувати підказку оптимізатора:

select /*+ PARALLEL(mytable, 12) */ count(*) from mytable;

Або увімкніть паралельний запит для всіх запитів у таблиці:

alter table mytable parallel 12;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.