Лучшая практика подсчета строк для подтверждения обратной связи перед их обработкой - PullRequest
0 голосов
/ 28 сентября 2018

Я ищу лучший способ подсчитать количество строк, которые я собираюсь использовать для некоторых исчислений, прежде чем использовать их.Причина в том, что мне нужно доказать обратную связь, например, «проанализировано 1/100 строк», «проанализировано 2/100 строк» ​​и т. Д.

Я говорю о 7000 строк и времени выполнениясчетчик отличается от 2 минут.

Хуже всего то, что сейчас мне нужно использовать запрос, чтобы получить счетчик, а затем открыть курсор, который полностью совпадает с предыдущим (за исключением счетчика).) и начинаем анализировать, поэтому код дублируется, и каждый раз, когда мне нужно изменить предложение where, мне приходится делать это дважды.

Я думал о том, чтобы поместить курсор в качестве локальной переменной, а затем запустить в pl / sql aЦикл while для увеличения счетчика, но я не уверен насчет производительности, поэтому я и прошу у вас несколько советов.

Действительно надеюсь, что ответы не будут заключаться в использовании некоторых магических свойствоткрытый курсор, который содержит общее количество строк, потому что я чувствую себя очень глупо: (

Если не доказано увеличение производительности, я предпочитаю не использовать счетчик (*) сверх (разделить на), потому что я считаю этоСлишком сложно понять с первого взгляда.

Спасибо всем

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018

Если вам нужно знать полное количество строк таблицы, вы можете использовать словарь данных num_rows (при условии, что статистика актуальна):

CREATE TABLE mytest AS SELECT * FROM all_objects;

BEGIN dbms_stats.gather_table_stats(user, 'MYTEST'); END;
/

SELECT num_rows FROM user_tables WHERE table_name='MYTEST';
-- 60715

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

EXPLAIN PLAN SET STATEMENT_ID = 'st1-seq' FOR 
  SELECT * FROM mytest WHERE object_type = 'SEQUENCE';
SELECT cardinality from plan_table WHERE statement_id='st1-seq' and operation='SELECT STATEMENT';
10

EXPLAIN PLAN SET STATEMENT_ID = 'st1-java' FOR 
  SELECT * FROM mytest WHERE object_type = 'JAVA CLASS';
SELECT cardinality from plan_table WHERE statement_id='st1-java' and operation='SELECT STATEMENT';
37563 
0 голосов
/ 28 сентября 2018

Вы можете использовать COUNT(*) OVER():

DECLARE
  CURSOR my_cur IS
  SELECT t.c, COUNT(*) OVER() AS total FROM tab t;

  v_c INT;
  v_total_rows INT;
  v_i INT :=0;
BEGIN
  OPEN my_cur;

  LOOP
    EXIT WHEN my_cur%NOTFOUND;
    FETCH my_cur INTO v_c, v_total_rows;

    IF v_i = 0 THEN
      DBMS_OUTPUT.put_line('Total number of rows to process: ' || v_total_rows);
    END IF;

    DBMS_OUTPUT.PUT_LINE('Current value :' || v_c);

    DBMS_OUTPUT.PUT_LINE('Progress: ' || 100.0 * v_i / v_total_rows || '%');
    v_i := v_i + 1;
  END LOOP;
  CLOSE my_cur;
END;
//

db <> fiddle demo


Вместо печати в DBMS_OUTPUT вы можете использовать SET_SESSION_LONGOPS

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...