Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Правильный ли я использую запрос?  [new]
poc
Member

Откуда:
Сообщений: 44
Необходимо выбрать из массива последние 30 строк, а из них еще первые 10 строк. Использую запрос:
SELECT ID,D FROM(SELECT ID,D FROM(SELECT ID,D FROM (SELECT ID,D FROM DATA ORDER BY ID DESC) WHERE ROWNUM <= 30)ORDER BY ID ASC)WHERE ROWNUM <= 10
Правильный лия использую запрос? Может есть варианты более быстрые и надежные? И в чем недостатки моего запроса?
21 мар 11, 23:02    [10405878]     Ответить | Цитировать Сообщить модератору
 Re: Правильный ли я использую запрос?  [new]
-2-
Member

Откуда:
Сообщений: 15330
poc,

row_number between 21 and 30
21 мар 11, 23:57    [10406050]     Ответить | Цитировать Сообщить модератору
 Re: Правильный ли я использую запрос?  [new]
AmKad
Member

Откуда:
Сообщений: 5222
poc,

+ Есть еще такой вариант, но гарантировать что он будет работать на ваших данных быстрее я не могу.
select *
from
   (select d.*, row_number() over (order by id desc) rn
    from data d
   ) 
where rn between 21 and 30;
21 мар 11, 23:57    [10406051]     Ответить | Цитировать Сообщить модератору
 Re: Правильный ли я использую запрос?  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 54381
такой запрос отработал за 25 сек
SELECT   ID, D
  FROM   (  SELECT   ID, D
              FROM   (SELECT   ID, D
                        FROM   (  SELECT   dk_idd id, nkniga D
                                    FROM   debet_kredit
                                ORDER BY   ID DESC)
                       WHERE   ROWNUM <= 30)
          ORDER BY   ID ASC)
 WHERE   ROWNUM <= 10

такой за 5 сек
SELECT   ID, dk.nkniga d
  FROM   (  SELECT   ID
              FROM   (SELECT   ID
                        FROM   (  SELECT   dk_idd id
                                    FROM   debet_kredit
                                ORDER BY   ID DESC)
                       WHERE   ROWNUM <= 30)
          ORDER BY   ID ASC) t, debet_kredit dk
 WHERE   ROWNUM <= 10
    and dk.dk_idd = t.id

а такой за 0.001 сек
SELECT   ID, D
  FROM   (  SELECT   ID, D
              FROM   (SELECT   ID, D
                        FROM   (  SELECT   dk_idd id, nkniga D
                                    FROM   debet_kredit
                                  where dk_idd >= (SELECT   max(dk_idd) id FROM   debet_kredit)-100
                                ORDER BY   ID DESC)
                       WHERE   ROWNUM <= 30)
          ORDER BY   ID ASC)
 WHERE   ROWNUM <= 10
результаты идентичны
в таблице debet_kredit 3.5 млн строк, партицирована, dk_idd - PK


Выделенная желтым строка является довольно спорной
22 мар 11, 00:15    [10406092]     Ответить | Цитировать Сообщить модератору
 Re: Правильный ли я использую запрос?  [new]
AmKad
Member

Откуда:
Сообщений: 5222
andreymx,

+ И все-таки стоит отметить что Ваш второй запрос - планозависимый
drop table data purge;

Таблица удалена.

Затрач.время: 00:00:00.04

create table data as
with s as
(select level id, rpad('x', 100, 'x') d from dual connect by level <= 1e6
)
select * from s;

Таблица создана.

Затрач.время: 00:00:03.35

SELECT ID,D FROM(SELECT ID,D FROM(SELECT ID,D FROM (SELECT ID,D FROM DATA ORDER BY ID DESC) WHERE ROWNUM <= 30)ORDER BY ID ASC)WHERE ROWNUM <= 10;

        ID D
---------- ----------------------------------------------------------------------------------------------------
    999971 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999972 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999973 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999974 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999975 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999976 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999977 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999978 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999979 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999980 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

10 строк выбрано.

Затрач.время: 00:00:03.75

План выполнения
----------------------------------------------------------
Plan hash value: 1706098915

--------------------------------------------------------------------------------------------
| Id  | Operation                   | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |      |    10 |   650 |       | 17718   (1)| 00:03:33 |
|*  1 |  COUNT STOPKEY              |      |       |       |       |            |          |
|   2 |   VIEW                      |      |    30 |  1950 |       | 17718   (1)| 00:03:33 |
|*  3 |    SORT ORDER BY STOPKEY    |      |    30 |  1950 |       | 17718   (1)| 00:03:33 |
|   4 |     VIEW                    |      |    30 |  1950 |       | 17717   (1)| 00:03:33 |
|*  5 |      COUNT STOPKEY          |      |       |       |       |            |          |
|   6 |       VIEW                  |      |   866K|    53M|       | 17717   (1)| 00:03:33 |
|*  7 |        SORT ORDER BY STOPKEY|      |   866K|    53M|    63M| 17717   (1)| 00:03:33 |
|   8 |         TABLE ACCESS FULL   | DATA |   866K|    53M|       |  4232   (1)| 00:00:51 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(ROWNUM<=10)
   3 - filter(ROWNUM<=10)
   5 - filter(ROWNUM<=30)
   7 - filter(ROWNUM<=30)

Note
-----
   - dynamic sampling used for this statement (level=2)


SELECT t.ID,  d
  FROM   (  SELECT   ID
              FROM   (SELECT   ID
                        FROM   (  SELECT   id
                                    FROM   data
                                ORDER BY   ID DESC)
                       WHERE   ROWNUM <= 30)
          ORDER BY   ID ASC) t, data dk
 WHERE   ROWNUM <= 10
    and dk.id = t.id;

        ID D
---------- ----------------------------------------------------------------------------------------------------
    999971 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999972 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999973 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999974 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999975 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999976 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999977 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999978 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999979 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999980 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

10 строк выбрано.

Затрач.время: 00:00:04.73

План выполнения
----------------------------------------------------------
Plan hash value: 1502966930

---------------------------------------------------------------------------------------------
| Id  | Operation                    | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |      |    10 |  1430 |       |  9945   (1)| 00:02:00 |
|*  1 |  COUNT STOPKEY               |      |       |       |       |            |          |
|*  2 |   HASH JOIN                  |      |    30 |  4290 |       |  9945   (1)| 00:02:00 |
|   3 |    VIEW                      |      |    30 |   390 |       |  8384   (1)| 00:01:41 |
|   4 |     SORT ORDER BY            |      |    30 |   390 |       |  8384   (1)| 00:01:41 |
|   5 |      VIEW                    |      |    30 |   390 |       |  8383   (1)| 00:01:41 |
|*  6 |       COUNT STOPKEY          |      |       |       |       |            |          |
|   7 |        VIEW                  |      |   866K|    10M|       |  8383   (1)| 00:01:41 |
|*  8 |         SORT ORDER BY STOPKEY|      |   866K|    10M|    16M|  8383   (1)| 00:01:41 |
|   9 |          TABLE ACCESS FULL   | DATA |   866K|    10M|       |  4230   (1)| 00:00:51 |
|  10 |    TABLE ACCESS FULL         | DATA |   866K|    53M|       |  1554   (1)| 00:00:19 |
---------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(ROWNUM<=10)
   2 - access("DK"."ID"="T"."ID")
   6 - filter(ROWNUM<=30)
   8 - filter(ROWNUM<=30)

Note
-----
   - dynamic sampling used for this statement (level=2)


SELECT /*+ use_hash(dk, t) leading(dk, t)*/ t.ID,  d
  FROM   (  SELECT   ID
              FROM   (SELECT   ID
                        FROM   (  SELECT   id
                                    FROM   data
                                ORDER BY   ID DESC)
                       WHERE   ROWNUM <= 30)
          ORDER BY   ID ASC) t, data dk
 WHERE   ROWNUM <= 10
    and dk.id = t.id;

        ID D
---------- ----------------------------------------------------------------------------------------------------
    999972 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999974 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999975 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999977 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999978 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999979 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999981 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999983 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999984 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    999985 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

10 строк выбрано.

Затрач.время: 00:00:07.14

План выполнения
----------------------------------------------------------
Plan hash value: 1609895996

---------------------------------------------------------------------------------------------
| Id  | Operation                    | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |      |    10 |   780 |       | 15782   (1)| 00:03:10 |
|*  1 |  COUNT STOPKEY               |      |       |       |       |            |          |
|*  2 |   HASH JOIN                  |      |    30 |  2340 |    63M| 15782   (1)| 00:03:10 |
|   3 |    TABLE ACCESS FULL         | DATA |   866K|    53M|       |  4232   (1)| 00:00:51 |
|   4 |    VIEW                      |      |    30 |   390 |       |  8384   (1)| 00:01:41 |
|   5 |     SORT ORDER BY            |      |    30 |   390 |       |  8384   (1)| 00:01:41 |
|   6 |      VIEW                    |      |    30 |   390 |       |  8383   (1)| 00:01:41 |
|*  7 |       COUNT STOPKEY          |      |       |       |       |            |          |
|   8 |        VIEW                  |      |   866K|    10M|       |  8383   (1)| 00:01:41 |
|*  9 |         SORT ORDER BY STOPKEY|      |   866K|    10M|    16M|  8383   (1)| 00:01:41 |
|  10 |          TABLE ACCESS FULL   | DATA |   866K|    10M|       |  4230   (1)| 00:00:51 |
---------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(ROWNUM<=10)
   2 - access("DK"."ID"="T"."ID")
   7 - filter(ROWNUM<=30)
   9 - filter(ROWNUM<=30)

Note
-----
   - dynamic sampling used for this statement (level=2)

22 мар 11, 00:40    [10406132]     Ответить | Цитировать Сообщить модератору
 Re: Правильный ли я использую запрос?  [new]
-2-
Member

Откуда:
Сообщений: 15330
andreymx,

А зачем по два раза сортировать и брать rownum?
22 мар 11, 00:44    [10406139]     Ответить | Цитировать Сообщить модератору
 Re: Правильный ли я использую запрос?  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 54381
AmKad
andreymx,

И все-таки стоит отметить что Ваш второй запрос - планозависимый
да я вроде и не отрицал
даже честно написал, что dk_idd - это PK
22 мар 11, 00:47    [10406150]     Ответить | Цитировать Сообщить модератору
 Re: Правильный ли я использую запрос?  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 54381
-2-
andreymx,

А зачем по два раза сортировать и брать rownum?
я просто показал минимальное отличие второго запроса от первого
22 мар 11, 00:49    [10406158]     Ответить | Цитировать Сообщить модератору
 Re: Правильный ли я использую запрос?  [new]
-2-
Member

Откуда:
Сообщений: 15330
andreymx
-2-
А зачем по два раза сортировать и брать rownum?
я просто показал минимальное отличие второго запроса от первого
Спросил про каждый запрос в отдельности. Почему не сделать between 21 and 30, на 30 строках копейки, но все же?
22 мар 11, 00:51    [10406162]     Ответить | Цитировать Сообщить модератору
 Re: Правильный ли я использую запрос?  [new]
Tolka
Member

Откуда:
Сообщений: 199
-2-
Почему не сделать between 21 and 30, на 30 строках копейки, но все же?


наверное, просто по-аналогии.

Для скорости важна самая первая обрезка по rownum <= 30. Когда в плане проскакивает COUNT STOPKEY.
А для того, чтобы написать
between 21 and 30
нужно
ROWNUM AS row_num
вычислить на предыдущем запросе и писать
row_num between 21 and 30
22 мар 11, 04:40    [10406266]     Ответить | Цитировать Сообщить модератору
 Re: Правильный ли я использую запрос?  [new]
poc
Member

Откуда:
Сообщений: 44
Уточню немного, строки в таблице имеют ID с пропусками некоторых номеров , поэтому просто сортировать по ID неполучаеться.
И хотелось бы всетаки понять какой запрос всетаки быстрее и лучше использовать?
Мой запрос или (row_number between 21 and 30 )?????
22 мар 11, 10:12    [10406836]     Ответить | Цитировать Сообщить модератору
 Re: Правильный ли я использую запрос?  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 54381
poc,

приведи статданные по таблице - размеры, динамику роста + скрипт


ЗЫ: Мой третий вариант таки самый быстрый :))
22 мар 11, 10:21    [10406883]     Ответить | Цитировать Сообщить модератору
 Re: Правильный ли я использую запрос?  [new]
AlexFF__|
Member

Откуда:
Сообщений: 2854
Всем, кто советовал что-то типа
between 21 and 30 
срочно чинить мозги много думать.
22 мар 11, 10:22    [10406886]     Ответить | Цитировать Сообщить модератору
 Re: Правильный ли я использую запрос?  [new]
AmKad
Member

Откуда:
Сообщений: 5222
AlexFF__|,

О чем думать?
22 мар 11, 11:38    [10407472]     Ответить | Цитировать Сообщить модератору
 Re: Правильный ли я использую запрос?  [new]
AmKad
Member

Откуда:
Сообщений: 5222
AmKad
AlexFF__|,

О чем думать?

Речь про случай, если в таблице меньше 30 строк?
22 мар 11, 11:42    [10407520]     Ответить | Цитировать Сообщить модератору
 Re: Правильный ли я использую запрос?  [new]
AlexFF__|
Member

Откуда:
Сообщений: 2854
AmKad
AmKad
AlexFF__|,

О чем думать?

Речь про случай, если в таблице меньше 30 строк?

Совершенно верно.

Особый цинизм ситуации в том, что ТС предложил правильный, быстро работающий вариант.
Ему же был предложен медленный, не всегда возвращающий правильные данные.
22 мар 11, 11:53    [10407616]     Ответить | Цитировать Сообщить модератору
 Re: Правильный ли я использую запрос?  [new]
AmKad
Member

Откуда:
Сообщений: 5222
AlexFF__|
AmKad
пропущено...

Речь про случай, если в таблице меньше 30 строк?

Совершенно верно.

Особый цинизм ситуации в том, что ТС предложил правильный, быстро работающий вариант.
Ему же был предложен медленный, не всегда возвращающий правильные данные.

Согласен.
22 мар 11, 11:55    [10407637]     Ответить | Цитировать Сообщить модератору
 Re: Правильный ли я использую запрос?  [new]
Tolka
Member

Откуда:
Сообщений: 199
AlexFF__|
AmKad
пропущено...

Речь про случай, если в таблице меньше 30 строк?

Совершенно верно.


Ну так зачем же сразу в крайности кидаться. Когда человек спрашивает про быстродействие запроса "первые (последние) N строк", то по-умолчанию подразумевается, что таблица большая. Исходя из этого и пишут 21 - 30
22 мар 11, 14:49    [10409034]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить