|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
Вопрос знатокам оптимизации производительности. Есть большая таблица TBL (CODE, NAME, CREATE_DATE, ...) с сотнями миллионов строк. Таблица парционирована по дате CREATE_DATE Код: plsql 1. 2. 3. 4. 5. 6.
Нужно подсчитать кол-во уникальных строк по перечисленным после дистинкта полям. Дистинкт делается очень долго. Без него кол-во считается быстро. Как бы обойтись без него? И подсчитать кол-во уникальных строк другим способом? Может посчитать всё, а потом дубли выкинуть? Если без дистинкта, то получается 20 млн строк. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 15:39 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
verter, сравните с SELECT count(DISTINCT to_char(nvl(CODE,-1),9999999)|| NAME) cc FROM TBL WHERE CREATE_DATE = to_date('2021.09.24','YYYY.MM.DD') ..... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 15:48 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
Stax сравните с SELECT count(DISTINCT to_char(nvl(CODE,-1),9999999)|| NAME) cc ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 15:57 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
Stax verter, сравните с SELECT count(DISTINCT to_char(nvl(CODE,-1),9999999)|| NAME) cc FROM TBL WHERE CREATE_DATE = to_date('2021.09.24','YYYY.MM.DD') ..... stax к сожалению стало даже дольше. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 16:11 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
verter, Используйте функцию APPROX_COUNT_DISTINCT Код: plsql 1. 2.
APPROX_COUNT_DISTINCT APPROX_COUNT_DISTINCT returns the approximate number of rows that contain a distinct value for expr. This function provides an alternative to the COUNT (DISTINCT expr) function, which returns the exact number of rows that contain distinct values of expr. APPROX_COUNT_DISTINCT processes large amounts of data significantly faster than COUNT, with negligible deviation from the exact result . For expr, you can specify a column of any scalar data type other than BFILE, BLOB, CLOB, LONG, LONG RAW, or NCLOB. APPROX_COUNT_DISTINCT ignores rows that contain a null value for expr. This function returns a NUMBER. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 16:40 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
verter Stax verter, сравните с SELECT count(DISTINCT to_char(nvl(CODE,-1),9999999)|| NAME) cc FROM TBL WHERE CREATE_DATE = to_date('2021.09.24','YYYY.MM.DD') ..... stax к сожалению стало даже дольше. А если сделать в два этапа: Код: plsql 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 16:54 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
flexgen А если сделать в два этапа ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 17:11 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
Таблица большая, параллелизма не было. APPROX_COUNT_DISTINCT сработала в 1.6 раза быстрее, чем COUNT(DISTINCT ... Результат c APPROX_COUNT_DISTINCT отличается на 3% от результата COUNT(DISTINCT ... Для большинства практических применений точность достаточная. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 17:24 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
SQL*Plus, да, проблема решается только включением параллельности, т.е. вот так: SELECT /*+PARALLEL(16)*/ COUNT(*) FROM ( SELECT DISTINCT CODE, NAME FROM TBL WHERE CREATE_DATE = to_date('2021.09.24','YYYY.MM.DD') ) ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 17:27 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
verter SQL*Plus, да, проблема решается только включением параллельности, т.е. вот так: SELECT /*+PARALLEL(16)*/ COUNT(*) FROM ( SELECT DISTINCT CODE, NAME FROM TBL WHERE CREATE_DATE = to_date('2021.09.24','YYYY.MM.DD') ) Включение параллельности увеличивает потребление ресурсов. В вашем случае раз в 18-20. За счет этого запрос выполняется быстрее. APPROX_COUNT_DISTINCT решает "проблему" за счет эффективности алгоритмов. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 17:31 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
AmKad А почему не в три? Да хоть в десять. Ни в чем себе не отказывай. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 17:33 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
SQL*Plus APPROX_COUNT_DISTINCT решает "проблему" за счет эффективности алгоритмов. Так то оно так, но если нужны точные значения, то APPROX_COUNT_DISTINCT не подойдет. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 17:39 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
Еще один пример на APPROX_COUNT_DISTINCT Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
C APPROX_COUNT_DISTINCT получил: Ускорение в 4+ раза Погрешность 0,8% ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 17:41 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
flexgen SQL*Plus APPROX_COUNT_DISTINCT решает "проблему" за счет эффективности алгоритмов. Так то оно так, но если нужны точные значения, то APPROX_COUNT_DISTINCT не подойдет. Приведите примеры, когда нужны точные значения для "Количества разных значений показателя". Для суммы по показателю - да нужны точные значения. Для количества значений показателя - да нужны точные значения, но уже не всегда. Для среднего арифметического значения показателя - да нужны точные значения, но уже не всегда - еще реже. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 17:44 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
verter SQL*Plus, да, проблема решается только включением параллельности, т.е. вот так: А ещё проблема может решаться (а может и не решаться) построением дополнительных индексов. Чтобы не гадать на кофейной гуще, лучше сразу бы приложили план с +ALLSTATS или репорт SQL Monitor. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 17:47 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
PuM256, индексы тут навряд ли помогут. Таблица парционирована по дате CREATE_DATE, поэтому такой запрос (без дистинкта) работает почти мгновенно: Код: plsql 1. 2. 3. 4. 5. 6.
дело именно в дистинкте. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 17:52 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
SQL*Plus Включение параллельности увеличивает потребление ресурсов. В вашем случае раз в 18-20. За счет этого запрос выполняется быстрее. APPROX_COUNT_DISTINCT решает "проблему" за счет эффективности алгоритмов. Да, вы совершенно правы! В моём случае APPROX_COUNT_DISTINCT отработал практически за такое же время что и с параллельностью. Код: plsql 1. 2. 3.
Время работы уменьшилось в 14 раз! потеря точности = 0.6% Жаль, что мне нужны точные результаты. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 17:59 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
SQL*Plus Приведите примеры, когда нужны точные значения для "Количества разных значений показателя". Да пожалуйста: verter Жаль, что мне нужны точные результаты. Я работаю в финансовой сфере, задачи, которые нам ставят всегда требуют точных данных. Всякие там усреднения, округления и тому подобное - для этого есть BI. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 18:07 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
verter Время работы уменьшилось в 14 раз! потеря точности = 0.6% Жаль, что мне нужны точные результаты . Зачем? Как вы их используете? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 18:08 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
flexgenзадачи, которые нам ставят всегда требуют точных данных И какие же задачи в финансовой сфере требуют "количество уникальных строк по перечисленным полям"?.. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 18:10 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
flexgen SQL*Plus Приведите примеры, когда нужны точные значения для "Количества разных значений показателя". Да пожалуйста: verter Жаль, что мне нужны точные результаты. Я работаю в финансовой сфере, задачи, которые нам ставят всегда требуют точных данных. Всякие там усреднения, округления и тому подобное - для этого есть BI. Это не пример. Это голословное эмоциональное утверждение. Приведите пример из вашей финансовой сферы, когда требуется использовать COUNT DISTINCT вообще и когда его нельзя заменить приблизительное значение. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 18:11 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
Как часто требуется выполнять такую операцию? Как часто её требуется выполнять относительно других операция по указанной таблице? Чем можно пожертвовать ради решения задачи (дисковое пространство, CPU, замедление других операций)? Требуется ли абсолютная точность в online или это подсчет постфактум? ...в конце концов, достаточных ли размеров sort area и нельзя ли её увеличить? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 18:18 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
SQL*Plus, Ну хорошо, вот пример - приходит некий аудитор и говорит, хочу знать количество транзакций, произведенных в определенном магазине, в определенный отрезок времени, определёнными кредитными картами. Мало того, хочу знать точное количество уникальных кредитных карт по организации, выдавшей эти карты, подпадающих под заданные параметры. И хочу знать количество транзакций, получивших разрешение кредитной компании, и количество транзакций, не получивших разрешение, а так же причины отказа. А у нас в день более 500 миллионов транзакций, плюс-минус 0.5% здесь не прокатит, ему точные данные подавай. Так что все зависит от постановки задачи, если устраивает приблизительное значение - то мы его и дадим. Но если от нас требуют точных данных - мы даем точные данные. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 18:31 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
Аудитор пару часов спокойно подождет точных данных, если они ему реально нужны. Но, полагаю, даже аудитор для оценки положения дел примет цифру с точностью +-1%. С третьей стороны, если Вы заранее знаете типовые вопросы аудитора, то ничто не мешает считать цифирь по закрытию банковского дня и откладывать в сторону. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 18:37 |
|
Замена DISTINCT
|
|||
---|---|---|---|
#18+
flexgen SQL*Plus, Ну хорошо, вот пример - приходит некий аудитор и говорит, хочу знать количество транзакций, произведенных в определенном магазине, в определенный отрезок времени, определёнными кредитными картами. Мало того, хочу знать точное количество уникальных кредитных карт по организации, выдавшей эти карты, подпадающих под заданные параметры. И хочу знать количество транзакций, получивших разрешение кредитной компании, и количество транзакций, не получивших разрешение, а так же причины отказа. А у нас в день более 500 миллионов транзакций, плюс-минус 0.5% здесь не прокатит, ему точные данные подавай. Так что все зависит от постановки задачи, если устраивает приблизительное значение - то мы его и дадим. Но если от нас требуют точных данных - мы даем точные данные. Дадите ему APPROX_COUNT_DISTINCT. Этого будет достаточно. "А то, понимаешь, ходят тут всякие и захотелками своими работать мешают". 2574256 и 2525562 это для практического применения одно и то же. Пример не убедительный. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 18:45 |
|
|
start [/forum/topic.php?fid=52&msg=40099901&tid=1879844]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
158ms |
get topic data: |
9ms |
get forum data: |
3ms |
get page messages: |
58ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 276ms |
0 / 0 |