powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / История одна дата vs две. Что лучше?
25 сообщений из 129, страница 3 из 6
История одна дата vs две. Что лучше?
    #35656183
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bogdanov Andrey пишет:

> Блин, забыл статистику актуализировать. Вот исправленный вариант -
> разница еще более впечатляющая :)

Ну так во втором случае у вас индексы не используются, насколько я могу
понять оракловые выкладки. А в первом используется.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35656185
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bogdanov Andrey пишет:

> Блин, забыл статистику актуализировать. Вот исправленный вариант -
> разница еще более впечатляющая :)

Первый запрос я понял что такое. А второй что ?
Вроде бы второго варианта структуры там нет. Что доказывали ?
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35656188
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bogdanov Andrey пишет:

> Ну и для сравнения, вариант с двумя датами:

Ну и здесь не используется индекс. подозреваю, что изза sysdate-1000
Вы заставте его использваться, а то
так не интересно.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35656401
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv
miksoft пишет:

> Например, Оракл не хранит в индексе те записи, у которых все поля в
> составе этого индекса IS NULL. Т.е. ни индекс (DateStart, DateEnd), ни

Ну, значит оракл плохая СУБД, и для этой задачи не подходит. Есть другие.

> индекс (DateEnd, DateStart) здесь не помогут. Можно, конечно, добавить
> третье поле, которое всегда NOT NULL, или на базе фукнции NVL сделать
> FBI-индекс.
> Но это решение уже
> а) обретает привязку к СУБД

Это третье поле-то -- привязка к СУБД ? И что, без функции никак ?

В общем, не вижу я тут ничего страшного.
Полно у нас таких запросов, ничего, работают. (правда, не на оракле)
Привязка к СУБД - это знанение особенностей хранения индексов в конкретной СУБД и FBI-индексы, которые есть не во всех СУБД.

Я и не говорю, что это страшно. Я говорил, что использование констант вместо NULL-ов для обозначения диапазонов будет удачнее. Не придется переписывать запрос, не придется задумываться об особенностях СУБД, не придется создавать дополнительные индексы. И Оракл сразу перестанет быть плохим :)
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35656655
Bogdanov Andrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЧТо за волшебный такой запрос, уже второй раз его в топике вижу.Ничего волшебного (и in вполне на равенство можно заменить - на работу оптимизатора в данном случае не влияет), а второй раз видите, потому что мне было лень его самому набивать, вот я и скопипастил :)
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35657078
Bogdanov Andrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv
Первый запрос я понял что такое. А второй что ?
Вроде бы второго варианта структуры там нет. Что доказывали ?

Вы не очень внимательно смотрели - там есть три варианта запроса. Первый - с одной датой, второй тоже с одной датой и с аналитической функцией (было утверждение, что в данном месте надо аналитику использовать), ну а третий - с двумя датами.

MasterZiv
Ну и здесь не используется индекс. подозреваю, что изза sysdate-1000
Вы заставте его использваться, а то так не интересно.

Эо я должен заставить? Увольте. Это пускай защитники варианта с двумя датами заставляют (подсказка: sysdate-1000 тут не причем). А потом посмотрим какой запрос в итоге проще и быстрее получится.
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35658062
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bogdanov Andrey,
Если не сложно, можете для третьего своего варианта сделать два отдельных индекса по датам (оракул не под рукой, сам проверить не могу), и выложить результаты?
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35658540
Bogdanov Andrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuHBogdanov Andrey,
Если не сложно, можете для третьего своего варианта сделать два отдельных индекса по датам (оракул не под рукой, сам проверить не могу), и выложить результаты?

Пожалуйста.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
SQL> create table hist(kod integer,start_dt date,end_dt date);

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

SQL> create index ix_hist_1 on hist(start_dt);

Индекс создан.

SQL> create index ix_hist_2 on hist(end_dt);

Индекс создан.

SQL> insert into hist(kod, start_dt,end_dt)
   2   select lv, sysdate-lv, sysdate-lv+ 1  from
   3   (select level as lv from dual connect by level <= 1000000 ) pivot;

 1000000  строк создано.

SQL> analyze table hist compute statistics;

Таблица проанализирована.

SQL> set autotrace on   
SQL> SELECT *
   2   FROM hist t1
   3   WHERE t1.start_dt < sysdate- 1000  and t1.end_dt >=sysdate- 1000 ;

       KOD START_DT END_DT
---------- -------- --------
       1000   21 . 02 . 06   22 . 02 . 06 


План выполнения
----------------------------------------------------------

------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)|
------------------------------------------------------------------------------
|    0  | SELECT STATEMENT            |           |   1000  |  18000  |     11    ( 0 )|
|*   1  |  TABLE ACCESS BY INDEX ROWID| HIST      |   1000  |  18000  |     11    ( 0 )|
|*   2  |   INDEX RANGE SCAN          | IX_HIST_2 |   1001  |       |      7    ( 0 )|
------------------------------------------------------------------------------

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

    1  - filter("T1"."START_DT"<SYSDATE@!- 1000 )
    2  - access("T1"."END_DT">=SYSDATE@!- 1000 )

Note
-----
   - 'PLAN_TABLE' is old version


Статистика
----------------------------------------------------------
           1   recursive calls
           0   db block gets
          13   consistent gets
          10   physical reads
           0   redo size
         452   bytes sent via SQL*Net to client
         373   bytes received via SQL*Net from client
           2   SQL*Net roundtrips to/from client
           0   sorts (memory)
           0   sorts (disk)
           1   rows processed

SQL> set autotrace off
SQL> drop table hist;
Oracle тут, конечно, красавец - выбрал правильный индекс. Если поставить sysdate-990000, то он другой индекc использует. Ну а количенство чтений зависит от расстояния до ближайшего края. И в худшем случае (sysdate-500000) составляет
3591 consistent gets
1697 physical reads

В варианте с запросом по одной дате
Код: plaintext
1.
2.
SELECT kod FROM hist t1
 WHERE t1.dt IN (SELECT max(t2.dt) FROM hist t2
                  WHERE t2.dt < sysdate -  500000 );
такой зависимости нет.
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35658768
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bogdanov Andrey пишет:

> Вы не очень внимательно смотрели - там есть три варианта запроса. Первый
> - с одной датой, второй тоже с одной датой и с аналитической функцией
> (было утверждение, что в данном месте надо аналитику использовать), ну а
> третий - с двумя датами.

Я это всё понял, но не про второй запрос. Теперь понял всё.

> Эо я должен заставить? Увольте. Это пускай защитники варианта с двумя
> датами заставляют (подсказка: sysdate-1000 тут не причем). А потом
> посмотрим какой запрос в итоге проще и быстрее получится.

Тогда в чем полезность вашего эксперементального сравнения ?
Оно просто безполезно.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35659402
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bogdanov Andrey,

Все-равно, чего-то я не понимаю...
Короче, не понимаю, почему оракул при условиях >, >=, <, <= для нескольких полей таблицы редко использует индексы по нескольким полям.

В приведенном примере - понятно, стало выгоднее делать TABLE ACCESS FULL и WINDOW SORT, чем поиск по индексу (START_DT, END_DT) или (START_DT). Поэтому, в первых результатах мы увидели такую картину.

А если сделать индекс по END_DT, START_DT он его схватит или нет?

Т.е. вообще иметь два индекса:
1) START_DT, END_DT
2) END_DT, START_DT

Давай попробуем вариант с такими индексами?
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35659449
Bogdanov Andrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivТогда в чем полезность вашего эксперементального сравнения ?
Оно просто безполезно.Как известно, бремя доказывания лежит на утверждающем. В топике были утверждения, что две даты однозначно дают выигрыш скорости при выборках. Причем мне показалось, что у людей нет ни тени сомнения - будучи уверенными, что вариант с одной датой очень плох начали даже предложения по его оптимизации выдвигать.
Мой эксперимент показывает, что ситуация ровно обратная. С одной датой очевидное решение дает отличные результаты, тогда как в варианте с двумя датами все не столь однозначно.
По крайней мере, теперь сторонники решения с двумя датами могут хоть немного призадуматься. Вот KOT MATPOCKuH уже начал пытаться выжать максимум из двух дат :)
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35659460
Bogdanov Andrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuHДавай попробуем вариант с такими индексами?Давайте. На всякий случай привожу результаты для трех разных дат:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
SQL> create table hist(kod integer,start_dt date,end_dt date);

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

SQL> create index ix_hist_1 on hist(start_dt,end_dt);

Индекс создан.

SQL> create index ix_hist_2 on hist(end_dt,start_dt);

Индекс создан.

SQL> insert into hist(kod, start_dt,end_dt)
   2   select lv, sysdate-lv, sysdate-lv+ 1  from
   3   (select level as lv from dual connect by level <= 1000000 ) pivot;

 1000000  строк создано.

SQL> analyze table hist compute statistics;

Таблица проанализирована.

SQL> set autotrace on   
SQL> SELECT *
   2   FROM hist t1
   3   WHERE t1.start_dt < sysdate- 1000  and t1.end_dt >=sysdate- 1000 ;

       KOD START_DT END_DT
---------- -------- --------
       1000   22 . 02 . 06   23 . 02 . 06 

План выполнения
------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)|
------------------------------------------------------------------------------
|    0  | SELECT STATEMENT            |           |   1000  |  18000  |     13    ( 0 )|
|    1  |  TABLE ACCESS BY INDEX ROWID| HIST      |   1000  |  18000  |     13    ( 0 )|
|*   2  |   INDEX RANGE SCAN          | IX_HIST_2 |   1000  |       |      9    ( 0 )|
------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
    2  - access("T1"."END_DT">=SYSDATE@!- 1000  AND "T1"."END_DT" IS NOT
              NULL)
       filter("T1"."START_DT"<SYSDATE@!- 1000 )

Статистика
----------------------------------------------------------
           1   recursive calls
           0   db block gets
          11   consistent gets
           9   physical reads
           0   redo size
         452   bytes sent via SQL*Net to client
         373   bytes received via SQL*Net from client
           2   SQL*Net roundtrips to/from client
           0   sorts (memory)
           0   sorts (disk)
           1   rows processed

SQL> SELECT *
   2   FROM hist t1
   3   WHERE t1.start_dt < sysdate- 990000  and t1.end_dt >=sysdate- 990000 ;

       KOD START_DT END_DT
---------- -------- --------
     990000   17 . 05 . 02   18 . 05 . 02 

План выполнения
------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)|
------------------------------------------------------------------------------
|    0  | SELECT STATEMENT            |           |   9900  |   174K|    109    ( 2 )|
|    1  |  TABLE ACCESS BY INDEX ROWID| HIST      |   9900  |   174K|    109    ( 2 )|
|*   2  |   INDEX RANGE SCAN          | IX_HIST_1 |   9900  |       |     73    ( 3 )|
------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
    2  - access("T1"."END_DT">=SYSDATE@!- 990000  AND
              "T1"."START_DT"<SYSDATE@!- 990000 )
       filter("T1"."END_DT">=SYSDATE@!- 990000 )

Статистика
----------------------------------------------------------
           1   recursive calls
           0   db block gets
          72   consistent gets
          67   physical reads
           0   redo size
         452   bytes sent via SQL*Net to client
         373   bytes received via SQL*Net from client
           2   SQL*Net roundtrips to/from client
           0   sorts (memory)
           0   sorts (disk)
           1   rows processed

SQL> SELECT *
   2   FROM hist t1
   3   WHERE t1.start_dt < sysdate- 500000  and t1.end_dt >=sysdate- 500000 ;

       KOD START_DT END_DT
---------- -------- --------
     500000   03 . 12 . 39   04 . 12 . 39 

План выполнения
---------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)|
---------------------------------------------------------------
|    0  | SELECT STATEMENT  |      |   250K|  4394K|    978   ( 20 )|
|*   1  |  TABLE ACCESS FULL| HIST |   250K|  4394K|    978   ( 20 )|
---------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
    1  - filter("T1"."START_DT"<SYSDATE@!- 500000  AND
              "T1"."END_DT">=SYSDATE@!- 500000 )

Статистика
----------------------------------------------------------
           1   recursive calls
           0   db block gets
        3591   consistent gets
        1293   physical reads
           0   redo size
         452   bytes sent via SQL*Net to client
         373   bytes received via SQL*Net from client
           2   SQL*Net roundtrips to/from client
           0   sorts (memory)
           0   sorts (disk)
           1   rows processed
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35659491
Bogdanov Andrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и на всякий случай, зависимость(точнее, ее отсутствие) от значения параметра для варианта с одной датой в таблице:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
SQL> create table hist(kod integer,dt date);

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

SQL> create index ix_hist_1 on hist(dt);

Индекс создан.

SQL> insert into hist(kod, dt)
   2   select lv, sysdate-lv from
   3   (select level as lv from dual connect by level <= 1000000 ) pivot;

 1000000  строк создано.

SQL> analyze table hist compute statistics;

Таблица проанализирована.

SQL> set autotrace on   
SQL> SELECT kod FROM hist t1
   2    WHERE t1.dt = (SELECT max(t2.dt) FROM hist t2
   3                     WHERE t2.dt < sysdate -  1000 );

       KOD
----------
       1000 

План выполнения
---------------------------------------------------------------------------------
| Id  | Operation                      | Name      | Rows  | Bytes | Cost (%CPU)|
---------------------------------------------------------------------------------
|    0  | SELECT STATEMENT               |           |      1  |     11  |      7    ( 0 )|
|    1  |  TABLE ACCESS BY INDEX ROWID   | HIST      |      1  |     11  |      4    ( 0 )|
|*   2  |   INDEX RANGE SCAN             | IX_HIST_1 |      1  |       |      3    ( 0 )|
|    3  |    SORT AGGREGATE              |           |      1  |      7  |            |
|    4  |     FIRST ROW                  |           |   999K|  6829K|      3    ( 0 )|
|*   5  |      INDEX RANGE SCAN (MIN/MAX)| IX_HIST_1 |   999K|  6829K|      3    ( 0 )|
---------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
    2  - access("T1"."DT"= (SELECT MAX("T2"."DT") FROM "HIST" "T2" WHERE
              "T2"."DT"<SYSDATE@!- 1000 ))
    5  - access("T2"."DT"<SYSDATE@!- 1000 )

Статистика
----------------------------------------------------------
           1   recursive calls
           0   db block gets
           8   consistent gets
           2   physical reads
           0   redo size
         330   bytes sent via SQL*Net to client
         373   bytes received via SQL*Net from client
           2   SQL*Net roundtrips to/from client
           0   sorts (memory)
           0   sorts (disk)
           1   rows processed

SQL> SELECT kod FROM hist t1
   2    WHERE t1.dt = (SELECT max(t2.dt) FROM hist t2
   3                     WHERE t2.dt < sysdate -  990000 );

       KOD
----------
     990000 

План выполнения
---------------------------------------------------------------------------------
| Id  | Operation                      | Name      | Rows  | Bytes | Cost (%CPU)|
---------------------------------------------------------------------------------
|    0  | SELECT STATEMENT               |           |      1  |     11  |      7    ( 0 )|
|    1  |  TABLE ACCESS BY INDEX ROWID   | HIST      |      1  |     11  |      4    ( 0 )|
|*   2  |   INDEX RANGE SCAN             | IX_HIST_1 |      1  |       |      3    ( 0 )|
|    3  |    SORT AGGREGATE              |           |      1  |      7  |            |
|    4  |     FIRST ROW                  |           |  10000  |  70000  |      3    ( 0 )|
|*   5  |      INDEX RANGE SCAN (MIN/MAX)| IX_HIST_1 |  10000  |  70000  |      3    ( 0 )|
---------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
    2  - access("T1"."DT"= (SELECT MAX("T2"."DT") FROM "HIST" "T2" WHERE
              "T2"."DT"<SYSDATE@!- 990000 ))
    5  - access("T2"."DT"<SYSDATE@!- 990000 )

Статистика
----------------------------------------------------------
           1   recursive calls
           0   db block gets
           8   consistent gets
           1   physical reads
           0   redo size
         330   bytes sent via SQL*Net to client
         373   bytes received via SQL*Net from client
           2   SQL*Net roundtrips to/from client
           0   sorts (memory)
           0   sorts (disk)
           1   rows processed

SQL> SELECT kod FROM hist t1
   2    WHERE t1.dt = (SELECT max(t2.dt) FROM hist t2
   3                     WHERE t2.dt < sysdate -  500000 );

       KOD
----------
     500000 

План выполнения
---------------------------------------------------------------------------------
| Id  | Operation                      | Name      | Rows  | Bytes | Cost (%CPU)|
---------------------------------------------------------------------------------
|    0  | SELECT STATEMENT               |           |      1  |     11  |      7    ( 0 )|
|    1  |  TABLE ACCESS BY INDEX ROWID   | HIST      |      1  |     11  |      4    ( 0 )|
|*   2  |   INDEX RANGE SCAN             | IX_HIST_1 |      1  |       |      3    ( 0 )|
|    3  |    SORT AGGREGATE              |           |      1  |      7  |            |
|    4  |     FIRST ROW                  |           |   500K|  3417K|      3    ( 0 )|
|*   5  |      INDEX RANGE SCAN (MIN/MAX)| IX_HIST_1 |   500K|  3417K|      3    ( 0 )|
---------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
    2  - access("T1"."DT"= (SELECT MAX("T2"."DT") FROM "HIST" "T2" WHERE
              "T2"."DT"<SYSDATE@!- 500000 ))
    5  - access("T2"."DT"<SYSDATE@!- 500000 )

Статистика
----------------------------------------------------------
           1   recursive calls
           0   db block gets
           8   consistent gets
           2   physical reads
           0   redo size
         330   bytes sent via SQL*Net to client
         373   bytes received via SQL*Net from client
           2   SQL*Net roundtrips to/from client
           0   sorts (memory)
           0   sorts (disk)
           1   rows processed

SQL> set autotrace off
SQL> drop table hist;

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

SQL> create table hist(kod integer,start_dt date,end_dt date);

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

SQL> create index ix_hist_1 on hist(start_dt,end_dt);

Индекс создан.

SQL> create index ix_hist_2 on hist(end_dt,start_dt);
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35659686
вопросик_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Bogdanov Andreyt1.start_dt < sysdate-500000 and t1.end_dt >=sysdate-500000
а почему вы для двух дат такое "вывернутое" условие задаете ? Намеренно сносите голову оптимизатору на специфических данных ?
Imho, нечто вроде сферического коня в вакууме.
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35659709
Bogdanov Andrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вопросик_а почему вы для двух дат такое "вывернутое" условие задаете ?Что именно "вывернутого" в этом условии? Как бы вы его написали? Если надо найти значение, которые было на дату sysdate-500000?
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35660430
Bely
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuHА если сделать индекс по END_DT, START_DT он его схватит или нет?

Т.е. вообще иметь два индекса:
1) START_DT, END_DT
2) END_DT, START_DTУ меня на маленьком тесте - он схватывал индекс, но радости от этого было мало. (Oracle 9.2)

Проблема составного индекса в том, что он по размеру БОЛЬШЕ чем индекс по одному полю и приходится считывать больше блоков. так что смысла в нем особого нет.

Есть у теста еще одна особенность - короткая запись в таблице (мало полей) из-за этого Full Table Scan иногда становится лучше чем поиск по индексу.

Я склоняюсь к мнению, что если использовать две даты, то строить надо только один индекс - по первой дате :)
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35660438
Bely
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Единственное когда две даты серьезно выиграют - это если в интервалах будут разрывы и время жизни товара не будет непрерывно.
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35660868
вопросик_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Bogdanov AndreyЕсли надо найти значение, которые было на дату sysdate-500000?
Для начала определитесь - у вас в таблице хранится один товар или разные ?

Если пачка разных - то тогда ваш первый запрос (который с одной датой) некорректен в приведенном вами виде;
если же один товар в таблице - то очевидно, для второго запроса (который с двумя датами) исходя из вполне здравых предположений - не должно возвращаться более одной записи(не должно быть на одну дату больше одной версии).

Тогда для двух дат запрос может быть примерно(навскидку, топорно) такой:
Код: plaintext
1.
2.
3.
4.
5.
  select * 
    from
     (select * from hist t1 where start_dt < sysdate- 1000  order by start_dt desc) 
  where 
     rownum< 2  and  end_dt >=sysdate- 1000 

PS аккуратнее сравнивать нужно
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35661002
Bely
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вопросик_Если пачка разных - то тогда ваш первый запрос (который с одной датой) некорректен в приведенном вами виде;
если же один товар в таблице - то очевидно, для второго запроса (который с двумя датами) исходя из вполне здравых предположений - не должно возвращаться более одной записи(не должно быть на одну дату больше одной версии).Для этого можно использовать дополнительную группировку по типу товара и скорее всего придется добавить поле "код товара" в индекс. И что это поменяет кардинально?
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35661012
вопросик_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BelyДля этого можно использовать дополнительную группировку по типу товара и скорее всего придется добавить поле "код товара" в индекс. И что это поменяет кардинально?
Кардинально ? Если без кода товара ? Я вам привел вариант с двумя датами. У вас же oracle ? Проверьте этот вариант и сравните с тем, что приводил Bogdanov Andrey. Результаты в студию, если не трудно.
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35661201
Bely
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вопросик_У вас же oracle ? Проверьте этот вариант и сравните с тем, что приводил Bogdanov Andrey. Результаты в студию, если не трудно.Оракл-то есть, со временем, к сожалению, туго...
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35661353
Bogdanov Andrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вопросик_PS аккуратнее сравнивать нужноВ качестве преимущества варианта с двумя датами указывалась простота запросов и их производительность. Причем в качестве простого запроса предлагался имеено вариант "тупо" сравнивающий искомую дату с границами диапазона.
Вы предложили "сложный" запрос, который для поиска записи фактически не использует вторую дату, то есть работает также как и для таблицы с одной датой. Вторая дата в вашем запросе используется только для отсечения случая разрывов в истории. Случай разрывов для варианта с одной датой в этом треде уже рассматривался, поэтому рассматривать его снова я смысла не вижу.

PS. Читать нужно перед тем как отвечать. :)
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35661611
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftMasterZivЕсли оптимизатор совсем тупой, переписываем

SELECT *
FROM Tovar_history
WHERE @date_now between DateStart and DateEnd
union all
SELECT *
FROM Tovar_history
WHERE DateEnd >= @date_now and DateStart IS NULL
union all
SELECT *
FROM Tovar_history
WHERE DateStart <= @date_now and DateEnd IS NULL
union all
SELECT *
FROM Tovar_history
WHERE DateStart IS NULL and DateEnd IS NULL

и приплыли...

вообще то нормальные люди null не заносят а заносят константы выходящие за диапазон к примеру: '01.01.1800' и '01.01.3000'
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35661626
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spmiksoftunion all
SELECT *
FROM Tovar_history
WHERE DateStart IS NULL and DateEnd IS NULL

и приплыли...вообще то нормальные люди null не заносят а заносят константы выходящие за диапазон к примеру: '01.01.1800' и '01.01.3000'Bogdanov AndreyЧитать нужно перед тем как отвечать. :)
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35663984
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sp пишет:

> вообще то нормальные люди null не заносят а заносят константы выходящие
> за диапазон к примеру: '01.01.1800' и '01.01.3000'

Это вы что-то перепутали. как раз нормальные люди используют для этого
специально придуманный для этого NULL.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
25 сообщений из 129, страница 3 из 6
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / История одна дата vs две. Что лучше?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]