SAMPLE / SAMPLE BLOCKв Oracle SQL. Введение
SAMPLE / SAMPLE BLOCK — это возможность Oracle SQL выбирать случайную подвыборку строк из таблицы.
Синтаксис позволяет управлять долей (в процентах) и воспроизводимостью через SEED.
Опция BLOCK использует блочное (по экстентам) семплирование — быстрее на больших таблицах, но менее равномерно на уровне отдельных строк.
Где используют
- Быстрая разведка данных: получить представление о распределениях без полного скана.
- Дешёвые проверки гипотез: тестировать JOIN‑ы, фильтры и агрегаты на подмножестве.
- Прототипы визуализаций: отрисовать графики и отчёты на подвыборке.
- Тесты производительности: сравнить планы запросов на частях данных.
Синтаксис
SELECT ...
FROM table_name [ t ]
SAMPLE [ BLOCK ] ( percentage )
[ SEED ( seed_value ) ]
[ WHERE ... ]
percentage— доля строк (0.000001 … 100);SEED— фиксирует генератор (одинаковый результат для одинакового зерна, если данные стабильны);BLOCK— быстрее на больших таблицах (читает целые блоки); может давать дисбаланс на мелких выборках.
Примечания: семпл выбирается на этапе доступа к таблице; семплирование нескольких таблиц независимо; проценты — ориентировочные.
100 примеров
1. Базовая случайная подвыборка 1%
SELECT *
FROM customers SAMPLE (3);2. Блочное семплирование 10% для логов
SELECT *
FROM app_logs SAMPLE BLOCK (10);3. Фиксируем результат через SEED(42)
SELECT *
FROM transactions SAMPLE (10) SEED (42);4. Семпл и фильтр в WHERE
SELECT order_id, amount
FROM orders SAMPLE (10)
WHERE status = 'PAID';5. Подвыборка и агрегаты в GROUP BY
SELECT country, COUNT(*) AS cnt
FROM customers SAMPLE (15)
GROUP BY country;6. Семпл в JOIN: семплируем только левую таблицу
SELECT o.order_id, c.customer_name
FROM orders SAMPLE (20) o
JOIN customers c ON c.customer_id = o.customer_id;7. Семпл в JOIN обеих таблиц
SELECT o.order_id, c.segment
FROM orders SAMPLE (1) o
JOIN customers SAMPLE (10) c ON c.customer_id = o.customer_id;8. Подвыборка с ORDER BY и ограничением результата
SELECT *
FROM products SAMPLE (2)
ORDER BY created_at
FETCH FIRST 100 ROWS ONLY;9. Блочное семплирование на партиционированной таблице
SELECT *
FROM sales_part SAMPLE BLOCK (20)
WHERE sales_date >= DATE '2025-01-01';10. Репликация результата: одинаковый SEED
SELECT COUNT(*) AS n1
FROM events SAMPLE (1) SEED (100);
-- Перезапуск с тем же SEED даст ту же мощность выборки (при неизменных данных)11. Вложенный подзапрос: семплируем подтаблицу
SELECT product_id, SUM(amount) AS total
FROM (
SELECT product_id, amount
FROM sales SAMPLE (20)
) s
GROUP BY product_id;12. Семпл и DISTINCT
SELECT DISTINCT country
FROM customers SAMPLE (2);13. Оценка среднего чека по подвыборке
SELECT AVG(amount) AS avg_check
FROM orders SAMPLE (10);14. Семпл по большим таблицам — блочный режим
SELECT *
FROM pageviews SAMPLE BLOCK (20)
WHERE url LIKE '/docs/%';15. Стабильная доля по ключу (альтернатива)
SELECT *
FROM orders
WHERE MOD(ORA_HASH(customer_id), 100) < 5;16. Сравнение двух долей подвыборки
SELECT 'small' AS tag, COUNT(*) AS n FROM orders SAMPLE (1)
UNION ALL
SELECT 'big' AS tag, COUNT(*) AS n FROM orders SAMPLE (1);17. Выборка и WINDOW‑аналитика
SELECT
customer_id,
SUM(amount) OVER (PARTITION BY customer_id) AS total_by_customer
FROM orders SAMPLE (0.5);18. Семпл и подмножество колонок
SELECT customer_id, created_at, country
FROM customers SAMPLE (7);19. Проверка гипотезы JOIN‑качества на подвыборке
SELECT COUNT(*) AS matches
FROM orders SAMPLE (20) o
JOIN shipments s ON s.order_id = o.order_id;20. Бенчмарк — сравнить планы на подвыборке
EXPLAIN PLAN FOR
SELECT /* test */ * FROM big_table SAMPLE (2);
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());Еще 20 примеров.
21. Блочное семплирование 20% с SEED
SELECT *
FROM app_logs SAMPLE BLOCK (20) SEED (77);22. Фиксированная подвыборка для отчёта дня
SELECT *
FROM transactions SAMPLE (3) SEED (TO_NUMBER(TO_CHAR(SYSDATE,'J')));23. Подвыборка и HAVING по сумме
SELECT product_id, SUM(amount) AS total
FROM sales SAMPLE (0.1)
GROUP BY product_id
HAVING SUM(amount) > 1000;24. Семпл в правой таблице JOIN
SELECT e.emp_id, d.dept_name
FROM employees e
JOIN departments SAMPLE (5) d ON d.dept_id = e.dept_id;25. Семпл с типичным WHERE‑фильтром
SELECT *
FROM sessions SAMPLE (1)
WHERE device = 'mobile' AND country = 'DE';26. Вложенный UNION ALL c семплом в каждом плече
SELECT 'A' src, COUNT(*) n FROM a SAMPLE (20)
UNION ALL
SELECT 'B' src, COUNT(*) n FROM b SAMPLE (10);27. Подвыборка для визуализации временного ряда
SELECT ts, metric
FROM metrics SAMPLE (8)
WHERE ts >= SYSTIMESTAMP - INTERVAL '7' DAY;28. Сэмпл и вычисляемые поля
SELECT order_id, amount, amount*0.2 AS vat
FROM orders SAMPLE (0.1);29. Блочный режим для больших архивов
SELECT *
FROM archive_audit SAMPLE BLOCK (10);30. Разные SEED для сравнения стабильности
SELECT COUNT(*) n FROM t SAMPLE (20) SEED (1);
SELECT COUNT(*) m FROM t SAMPLE (1) SEED (2);31. Подвыборка и оконная медиана
SELECT
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY amount) AS p50
FROM orders SAMPLE (0.5);32. Семпл перед материализацией во временную таблицу
CREATE GLOBAL TEMPORARY TABLE tmp_orders AS
SELECT * FROM orders SAMPLE (20);33. Сэмпл и удаление дубликатов
SELECT DISTINCT customer_id
FROM orders SAMPLE (15);34. Фиксируем дневной SEED от даты
SELECT *
FROM big_table SAMPLE (15) SEED (TO_NUMBER(TO_CHAR(CURRENT_DATE,'DDD')));35. Подвыборка с сортировкой по времени
SELECT *
FROM events SAMPLE (15)
ORDER BY event_ts DESC;36. Семпл в подзапросе внутри WHERE IN
SELECT *
FROM customers
WHERE customer_id IN (
SELECT customer_id
FROM orders SAMPLE (3)
);37. Подвыборка для быстрой валидации схемы
SELECT table_name, column_name, data_type
FROM user_tab_columns SAMPLE (20);38. Блочный режим на партиции за месяц
SELECT *
FROM sales_2025_01 SAMPLE BLOCK (12);39. Сэмпл и вычисление DISTINCT‑количества
SELECT COUNT(DISTINCT customer_id) AS dc
FROM orders SAMPLE (12);40. Прототип отчёта: топ‑категории на подвыборке
SELECT category, SUM(amount) AS total
FROM sales SAMPLE (5)
GROUP BY category
ORDER BY total DESC
FETCH FIRST 10 ROWS ONLY;Еще 20 примеров.
41. Базовая случайная подвыборка 1%
SELECT *
FROM customers SAMPLE (1);42. Блочное семплирование 10% для логов
SELECT *
FROM app_logs SAMPLE BLOCK (25);43. Фиксируем результат через SEED(42)
SELECT *
FROM transactions SAMPLE (3) SEED (42);44. Семпл и фильтр в WHERE
SELECT order_id, amount
FROM orders SAMPLE (4)
WHERE status = 'PAID';45. Подвыборка и агрегаты в GROUP BY
SELECT country, COUNT(*) AS cnt
FROM customers SAMPLE (20)
GROUP BY country;46. Семпл в JOIN: семплируем только левую таблицу
SELECT o.order_id, c.customer_name
FROM orders SAMPLE (2) o
JOIN customers c ON c.customer_id = o.customer_id;47. Семпл в JOIN обеих таблиц
SELECT o.order_id, c.segment
FROM orders SAMPLE (6) o
JOIN customers SAMPLE (15) c ON c.customer_id = o.customer_id;48. Подвыборка с ORDER BY и ограничением результата
SELECT *
FROM products SAMPLE (7)
ORDER BY created_at
FETCH FIRST 100 ROWS ONLY;49. Блочное семплирование на партиционированной таблице
SELECT *
FROM sales_part SAMPLE BLOCK (15)
WHERE sales_date >= DATE '2025-01-01';50. Репликация результата: одинаковый SEED
SELECT COUNT(*) AS n1
FROM events SAMPLE (5) SEED (100);
-- Перезапуск с тем же SEED даст ту же мощность выборки (при неизменных данных)51. Вложенный подзапрос: семплируем подтаблицу
SELECT product_id, SUM(amount) AS total
FROM (
SELECT product_id, amount
FROM sales SAMPLE (10)
) s
GROUP BY product_id;52. Семпл и DISTINCT
SELECT DISTINCT country
FROM customers SAMPLE (4);53. Оценка среднего чека по подвыборке
SELECT AVG(amount) AS avg_check
FROM orders SAMPLE (5);54. Семпл по большим таблицам — блочный режим
SELECT *
FROM pageviews SAMPLE BLOCK (20)
WHERE url LIKE '/docs/%';55. Стабильная доля по ключу (альтернатива)
SELECT *
FROM orders
WHERE MOD(ORA_HASH(customer_id), 100) < 5;56. Сравнение двух долей подвыборки
SELECT 'small' AS tag, COUNT(*) AS n FROM orders SAMPLE (4)
UNION ALL
SELECT 'big' AS tag, COUNT(*) AS n FROM orders SAMPLE (10);57. Выборка и WINDOW‑аналитика
SELECT
customer_id,
SUM(amount) OVER (PARTITION BY customer_id) AS total_by_customer
FROM orders SAMPLE (0.5);58. Семпл и подмножество колонок
SELECT customer_id, created_at, country
FROM customers SAMPLE (4);59. Проверка гипотезы JOIN‑качества на подвыборке
SELECT COUNT(*) AS matches
FROM orders SAMPLE (20) o
JOIN shipments s ON s.order_id = o.order_id;60. Бенчмарк — сравнить планы на подвыборке
EXPLAIN PLAN FOR
SELECT /* test */ * FROM big_table SAMPLE (8);
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());Еще 20 примеров.
61. Блочное семплирование 20% с SEED
SELECT *
FROM app_logs SAMPLE BLOCK (25) SEED (77);62. Фиксированная подвыборка для отчёта дня
SELECT *
FROM transactions SAMPLE (10) SEED (TO_NUMBER(TO_CHAR(SYSDATE,'J')));63. Подвыборка и HAVING по сумме
SELECT product_id, SUM(amount) AS total
FROM sales SAMPLE (3)
GROUP BY product_id
HAVING SUM(amount) > 1000;64. Семпл в правой таблице JOIN
SELECT e.emp_id, d.dept_name
FROM employees e
JOIN departments SAMPLE (12) d ON d.dept_id = e.dept_id;65. Семпл с типичным WHERE‑фильтром
SELECT *
FROM sessions SAMPLE (6)
WHERE device = 'mobile' AND country = 'DE';66. Вложенный UNION ALL c семплом в каждом плече
SELECT 'A' src, COUNT(*) n FROM a SAMPLE (7)
UNION ALL
SELECT 'B' src, COUNT(*) n FROM b SAMPLE (8);67. Подвыборка для визуализации временного ряда
SELECT ts, metric
FROM metrics SAMPLE (12)
WHERE ts >= SYSTIMESTAMP - INTERVAL '7' DAY;68. Сэмпл и вычисляемые поля
SELECT order_id, amount, amount*0.2 AS vat
FROM orders SAMPLE (1);69. Блочный режим для больших архивов
SELECT *
FROM archive_audit SAMPLE BLOCK (12);70. Разные SEED для сравнения стабильности
SELECT COUNT(*) n FROM t SAMPLE (10) SEED (1);
SELECT COUNT(*) m FROM t SAMPLE (12) SEED (2);71. Подвыборка и оконная медиана
SELECT
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY amount) AS p50
FROM orders SAMPLE (6);72. Семпл перед материализацией во временную таблицу
CREATE GLOBAL TEMPORARY TABLE tmp_orders AS
SELECT * FROM orders SAMPLE (7);73. Сэмпл и удаление дубликатов
SELECT DISTINCT customer_id
FROM orders SAMPLE (1);74. Фиксируем дневной SEED от даты
SELECT *
FROM big_table SAMPLE (3) SEED (TO_NUMBER(TO_CHAR(CURRENT_DATE,'DDD')));75. Подвыборка с сортировкой по времени
SELECT *
FROM events SAMPLE (2)
ORDER BY event_ts DESC;76. Семпл в подзапросе внутри WHERE IN
SELECT *
FROM customers
WHERE customer_id IN (
SELECT customer_id
FROM orders SAMPLE (1)
);77. Подвыборка для быстрой валидации схемы
SELECT table_name, column_name, data_type
FROM user_tab_columns SAMPLE (7);78. Блочный режим на партиции за месяц
SELECT *
FROM sales_2025_01 SAMPLE BLOCK (10);79. Сэмпл и вычисление DISTINCT‑количества
SELECT COUNT(DISTINCT customer_id) AS dc
FROM orders SAMPLE (3);80. Прототип отчёта: топ‑категории на подвыборке
SELECT category, SUM(amount) AS total
FROM sales SAMPLE (4)
GROUP BY category
ORDER BY total DESC
FETCH FIRST 10 ROWS ONLY;Еще 20 примеров.
81. Базовая случайная подвыборка 1%
SELECT *
FROM customers SAMPLE (6);82. Блочное семплирование 10% для логов
SELECT *
FROM app_logs SAMPLE BLOCK (10);83. Фиксируем результат через SEED(42)
SELECT *
FROM transactions SAMPLE (8) SEED (42);84. Семпл и фильтр в WHERE
SELECT order_id, amount
FROM orders SAMPLE (3)
WHERE status = 'PAID';85. Подвыборка и агрегаты в GROUP BY
SELECT country, COUNT(*) AS cnt
FROM customers SAMPLE (5)
GROUP BY country;86. Семпл в JOIN: семплируем только левую таблицу
SELECT o.order_id, c.customer_name
FROM orders SAMPLE (1) o
JOIN customers c ON c.customer_id = o.customer_id;87. Семпл в JOIN обеих таблиц
SELECT o.order_id, c.segment
FROM orders SAMPLE (8) o
JOIN customers SAMPLE (6) c ON c.customer_id = o.customer_id;88. Подвыборка с ORDER BY и ограничением результата
SELECT *
FROM products SAMPLE (7)
ORDER BY created_at
FETCH FIRST 100 ROWS ONLY;89. Блочное семплирование на партиционированной таблице
SELECT *
FROM sales_part SAMPLE BLOCK (8)
WHERE sales_date >= DATE '2025-01-01';90. Репликация результата: одинаковый SEED
SELECT COUNT(*) AS n1
FROM events SAMPLE (8) SEED (100);
-- Перезапуск с тем же SEED даст ту же мощность выборки (при неизменных данных)91. Вложенный подзапрос: семплируем подтаблицу
SELECT product_id, SUM(amount) AS total
FROM (
SELECT product_id, amount
FROM sales SAMPLE (2)
) s
GROUP BY product_id;92. Семпл и DISTINCT
SELECT DISTINCT country
FROM customers SAMPLE (2);93. Оценка среднего чека по подвыборке
SELECT AVG(amount) AS avg_check
FROM orders SAMPLE (12);94. Семпл по большим таблицам — блочный режим
SELECT *
FROM pageviews SAMPLE BLOCK (10)
WHERE url LIKE '/docs/%';95. Стабильная доля по ключу (альтернатива)
SELECT *
FROM orders
WHERE MOD(ORA_HASH(customer_id), 100) < 5;96. Сравнение двух долей подвыборки
SELECT 'small' AS tag, COUNT(*) AS n FROM orders SAMPLE (1)
UNION ALL
SELECT 'big' AS tag, COUNT(*) AS n FROM orders SAMPLE (0.5);97. Выборка и WINDOW‑аналитика
SELECT
customer_id,
SUM(amount) OVER (PARTITION BY customer_id) AS total_by_customer
FROM orders SAMPLE (5);98. Семпл и подмножество колонок
SELECT customer_id, created_at, country
FROM customers SAMPLE (10);99. Проверка гипотезы JOIN‑качества на подвыборке
SELECT COUNT(*) AS matches
FROM orders SAMPLE (10) o
JOIN shipments s ON s.order_id = o.order_id;100. Бенчмарк — сравнить планы на подвыборке
EXPLAIN PLAN FOR
SELECT /* test */ * FROM big_table SAMPLE (6);
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());Частые ошибки и подводные камни
- Непостоянство без SEED. Каждый запуск без
SEEDдаёт иную подвыборку. - Переоценка равномерности.
BLOCKможет смещать доли по регионам/датам, если данные кластеризованы. - Малые проценты. При 0.1% на маленьких таблицах можно получить 0 строк.
- Индексные доступы. Семплирование относится к таблице; индексы не «семплируются».
- JOIN‑эффект. Семплирование каждой таблицы независимо: перехлёст по ключам случаен.
Альтернативы
- Псевдослучайный фильтр:
WHERE MOD(ORA_HASH(key), 100) < 5— стабильная доля по ключу. - Генератор:
WHERE DBMS_RANDOM.VALUE < 0.05— строковое семплирование безBLOCK. - Материализация подвыборки во временную таблицу для повторного использования.
Заключение
SAMPLE помогает быстро смотреть на большие таблицы и строить прототипы без долгих сканов.
Используйте SEED для воспроизводимости, а при кластеризованных данных сравните результаты с хэш‑фильтрами по ключу.
Документация
Oracle SQL Reference — SELECT (табличное семплирование)
Следующая статья:
KEEP в Oracle SQL — как выбрать максимум или минимум