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

Набросал запросы, которые надо реализовать для 2х вариантов(выбор наименования, цены на определенную дату; просмотр истории наименований, цены больше/меньше заданной даты; длительность действия данного наименования, цены для данного товара). В первом варианте запросы сложнее, но ничего особо страшного я не заметил. Или я не прав и чего-то не вижу и такая схема может потом замедлить работу системы?

В первом варианте меня смущает необходимость вставки записи дополнительных записей для временного прекращения истории(строка с датой и без наименования) и для окончания ведения истории без удаления товара(последнее наименование и дата). Можно ли этого избежать и сделать по-другому?

При рассмотрении второго варианта смущают правки соседних записей, т.к. предполагается, что история будет активно редактироваться. Возможны случаи:
Код: plaintext
1.
2.
3.
  >  1       1  tov1  01 . 05 . 08   10 . 02 . 08 
  >  2       1  tov2  10 . 02 . 08   15 . 03 . 08 
  >  3       1  tov3  15 . 03 . 08   18 . 03 . 08 
Надо удалить, запись 2 - это приводит к редактированию даты в записи 1
Или вставить запись 1 tov2.1 20.02.08 10.03.08 - надо редактировать запись 3
Может возникнуть необходимость редактирования даты окончания действия наименования
tov2 до 17.03.08 - в этом случае начало действия наименования tov3 надо будет сдвигать
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35651941
korda
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
После всего прочитанного все больше склоняюсь к первому варианту. Во втором есть ещё один недостаток - одна и таже дата по сути дела продублирована в двух местах, ведь дата окончания одного периода совпадает с датой начала следующего.

Второй вариант можно рассматривать и как промежуточную таблицу, производимую по исходной в целях оптимизации запросов.

По поводу "временного прекращения действия истории", кажется мне, что здесь что-то не то, что нужную Вам функциональность можно и нужно реализовать как-то по другому, не внося в идею непрерывной истории дополнительные факторы усложняющие общую картину, ведь в первом варианте, если рассматривать его в чистом виде, мы имеем, по сути дела, своеобразный лог изменения записей. Кстати, то, что это лог, делает первый вариант ещё более симпатичным, так как лог - вещь известная, стандартная. Возможно позже, Вы даже захотите использовать готовые инструменты для его анализа.
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35652011
korda
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ChA
kordaНапример, в таблице с полями Пол, Беременность, второе поле для женщин может принимать значения TRUE или FALSE, а для мужчин - NULL, следовательно можно говорить, что поля Беременность и Пол находятся в зависимости. Что в этом плохого?Только то, что мужчина может оказаться беременным, а женщина - в неизвестном медицине состоянии. Вы можете использовать такое решение, но не удивляйтесь сюрпризам. В общем случае, это неправильный подход.


Вы правы, я не подумал... В данном случае, поле Беременность не должно присутствовать в таблице Люди, а должно находиться в таблице Женщины и отсутствовать в таблице Мужчины.
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35652251
korda
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я перечитал свой пост в другой теме (см. выше) и понял, что написанные ChA запросы могут быть с успехом применены и к первому варианту. Получается, что дата окончания, в той-же самой записи просто не нужна!

Получение состояния исходной таблицы на определённую дату:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
SELECT *
FROM hist t1
WHERE t1.dt IN (
	SELECT max(t2.dt)
	FROM hist t2
	WHERE t2.kod = t1.kod AND '2009-12-20' > t2.dt
)
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35652730
Bely
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kordaчто дата окончания, в той-же самой записи просто не нужна! А Oracle в своих Flashback Archive Tables, почему-то, использует две даты в своих системных таблицах (а точнее START_SCN, END_SCN).

Вот и получается, что "Мужики-то не знают..." (с)
или там дураки сидят, пологаете?
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35652972
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoft пишет:


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

О чём вы вообще говорите ? Это - обычная бизнес-логика, и достаточно простая.
Реализуется элементарно в ЛЮБОЙ современной СУБД на триггерах или на процедурах.
В чём проблема там у вас -- я не понимаю.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35652976
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoft пишет:

> Тогда придется писать
>
> SELECT * FROM Tovar_history
> WHERE (DateStart<NOW() OR DateStart IS NULL) AND (NOW()<DateEnd OR DateEnd IS NULL)
>
> На мой взгляд, индексы тут неприменимы.

Предлагаю его переписать так:

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

И всё уже применимо в полный рост
(два индекса по (DateStart, DateEnd) и (DateEnd,DateStart) ).

Если оптимизатор совсем тупой, переписываем

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
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35652982
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Novice22 пишет:

> наименования, цены для данного товара). В первом варианте запросы
> сложнее, но ничего особо страшного я не заметил. Или я не прав и чего-то
> не вижу и такая схема может потом замедлить работу системы?

Так может пошлёте ?
>
> В первом варианте меня смущает необходимость вставки записи
> дополнительных записей для временного прекращения истории(строка с датой
> и без наименования) и для окончания ведения истории без удаления
> товара(последнее наименование и дата).

О! А я предупреждал ...

> Может возникнуть необходимость редактирования даты окончания действия
> наименования
> tov2 до 17.03.08 - в этом случае начало действия наименования tov3 надо
> будет сдвигать

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

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

и приплыли...
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35653046
korda
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Belykordaчто дата окончания, в той-же самой записи просто не нужна! А Oracle в своих Flashback Archive Tables, почему-то, использует две даты в своих системных таблицах (а точнее START_SCN, END_SCN).

Вот и получается, что "Мужики-то не знают..." (с)
или там дураки сидят, пологаете?

Может быть для такого подхода у Oracle имеются какие-то объективные причины. Скорость выполнения запросов или ещё что-то... Кстати, как Вы думаете, почему они так делают?
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35653139
Cheprasov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мне кажется дату за ключ вообще брать не нужно, добавить в таблицу истории свое уникальное поле, а по полям id дата создать индекс
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35653644
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что по вашему быстрее работать будет и меньше ресурсов потреблять:
korda
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
SELECT *
FROM hist t1
WHERE t1.kod = 'Сосиски'
    AND t1.dt IN (
	SELECT max(t2.dt)
	FROM hist t2
	WHERE t2.kod = t1.kod AND '2009-12-20' > t2.dt
)
[/quot]

или

Код: plaintext
1.
2.
3.
4.
5.
SELECT *
FROM hist t1
WHERE t1.kod = 'Сосиски'
    AND '2009-12-20' >= t1.start_date
    AND '2009-12-20' < t1.end_date

А проще - попробуйте на своей БД: создайте табличку, залейте туда 10 000 000 записей - и вперед!

Результаты - в студию!
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35653787
Bogdanov Andrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuHЧто по вашему быстрее работать будет и меньше ресурсов потреблять:В такой постановке вопроса первый вариант выиграет однозначно. Во втором варианте еще и не всякий оптимизатор индекс догадается поиметь.

Второй вариант может выиграть на запросах типа
Код: plaintext
select sum(ostatok) from hist where dt_start<=:date and dt_end>:date;
То есть когда нас интересуют некие аналитики на заданную дату.
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35653796
Bely
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kordaМожет быть для такого подхода у Oracle имеются какие-то объективные причины. Скорость выполнения запросов или ещё что-то...Вы сами ответили - скорость выполнения запросов.
Для принятия решения о попадании строки в выборку - для двух дат нужна только эта строка.
Для одной даты - надо найти еще вторую строку, которая укажет конец интервала.

2 KOT MATPOCKuH
Всетаки, для первого запроса надо использовать аналитические функции.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT  t2.*
FROM
(
SELECT t1.dt as dt_start
  , lead(t1.dt) over (partition by t1.kod order by t1.dt, t1.id) as dt_end
  , t1.id, t1.kod
FROM hist t1
) t2
WHERE  1 = 1 
  AND '2009-12-20' >= t2.dt_start
  AND '2009-12-20' < t3.dt_end
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35653902
Bogdanov Andrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BelyВсетаки, для первого запроса надо использовать аналитические функции.Лучше не надо :)

Код: 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.
SQL> create table hist(kod integer,dt date);

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

SQL> create index ix_hist on hist(dt);

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

SQL> 
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> 
SQL> set autotrace on   
SQL> 
SQL> SELECT kod FROM hist t1
   2   WHERE t1.dt IN (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  |     22  |      7    ( 0 )|
|    1  |  TABLE ACCESS BY INDEX ROWID   | HIST    |      1  |     22  |      5    ( 0 )|
|*   2  |   INDEX RANGE SCAN             | IX_HIST |   4005  |       |      1    ( 0 )|
|    3  |    SORT AGGREGATE              |         |      1  |      9  |            |
|    4  |     FIRST ROW                  |         |  1001K|  8799K|      2    ( 0 )|
|*   5  |      INDEX RANGE SCAN (MIN/MAX)| IX_HIST |  1001K|  8799K|      2    ( 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 )

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


Статистика
----------------------------------------------------------
          36   recursive calls
           0   db block gets
         167   consistent gets
         461   physical reads
          72   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> 
SQL> SELECT  kod
   2   FROM (SELECT t1.dt as dt_start
   3     , lead(t1.dt) over (order by t1.dt) as dt_end
   4     , t1.kod
   5   FROM hist t1
   6   ) t2
   7   WHERE  1 = 1 
   8     AND t2.dt_start <= sysdate- 1000 
   9     AND t2.dt_end > sysdate- 1000 ;

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


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

-------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes |TempSpc| Cost (%CPU)|
-------------------------------------------------------------------------
|    0  | SELECT STATEMENT    |      |  1001K|    29M|       |   7400    ( 4 )|
|*   1  |  VIEW               |      |  1001K|    29M|       |   7400    ( 4 )|
|    2  |   WINDOW SORT       |      |  1001K|    21M|    61M|   7400    ( 4 )|
|    3  |    TABLE ACCESS FULL| HIST |  1001K|    21M|       |    581    ( 7 )|
-------------------------------------------------------------------------

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

    1  - filter("T2"."DT_START"<=SYSDATE@!- 1000  AND
              "T2"."DT_END">SYSDATE@!- 1000 )

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


Статистика
----------------------------------------------------------
           4   recursive calls
           0   db block gets
        2552   consistent gets
        1816   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
           1   sorts (memory)
           0   sorts (disk)
           1   rows processed

SQL> 
SQL> set autotrace off
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35653907
Bogdanov Andrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bogdanov Andrey,
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35653911
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.
SQL> create table hist(kod integer,dt date);

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

SQL> create index ix_hist on hist(dt);

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

SQL> 
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> 
SQL> analyze table hist compute statistics;

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

SQL> set autotrace on   
SQL> 
SQL> SELECT kod FROM hist t1
   2   WHERE t1.dt IN (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  |       |      3    ( 0 )|
|    3  |    SORT AGGREGATE              |         |      1  |      7  |            |
|    4  |     FIRST ROW                  |         |   999K|  6829K|      3    ( 0 )|
|*   5  |      INDEX RANGE SCAN (MIN/MAX)| IX_HIST |   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 )

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


Статистика
----------------------------------------------------------
           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> 
SQL> SELECT  kod
   2   FROM (SELECT t1.dt as dt_start
   3     , lead(t1.dt) over (order by t1.dt) as dt_end
   4     , t1.kod
   5   FROM hist t1
   6   ) t2
   7   WHERE  1 = 1 
   8     AND t2.dt_start <= sysdate- 1000 
   9     AND t2.dt_end > sysdate- 1000 ;

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


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

-------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes |TempSpc| Cost (%CPU)|
-------------------------------------------------------------------------
|    0  | SELECT STATEMENT    |      |  1000K|    29M|       |   5117    ( 5 )|
|*   1  |  VIEW               |      |  1000K|    29M|       |   5117    ( 5 )|
|    2  |   WINDOW SORT       |      |  1000K|    10M|    38M|   5117    ( 5 )|
|    3  |    TABLE ACCESS FULL| HIST |  1000K|    10M|       |    581    ( 7 )|
-------------------------------------------------------------------------

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

    1  - filter("T2"."DT_START"<=SYSDATE@!- 1000  AND
              "T2"."DT_END">SYSDATE@!- 1000 )

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


Статистика
----------------------------------------------------------
           1   recursive calls
           0   db block gets
        2482   consistent gets
         193   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
           1   sorts (memory)
           0   sorts (disk)
           1   rows processed

SQL> 
SQL> set autotrace off
SQL> 
SQL> drop table hist;

Таблица удалена.
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35653921
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.
SQL> create table hist(kod integer,start_dt date,end_dt date);

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

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

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

SQL> 
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> 
SQL> analyze table hist compute statistics;

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

SQL> 
SQL> set autotrace on   
SQL> 
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   18 . 02 . 06   19 . 02 . 06 


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

---------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)|
---------------------------------------------------------------
|    0  | SELECT STATEMENT  |      |   1000  |  18000  |    928   ( 16 )|
|*   1  |  TABLE ACCESS FULL| HIST |   1000  |  18000  |    928   ( 16 )|
---------------------------------------------------------------

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

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

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


Статистика
----------------------------------------------------------
           1   recursive calls
           0   db block gets
        3591   consistent gets
        1652   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> 
SQL> drop table hist;
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35653986
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoft пишет:
> Автор: "miksoft"
> MasterZiv
> Если оптимизатор совсем тупой, переписываем
>
> 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
>
> и приплыли...
Куда приплыли-то? Чем вам это не нравится, даже если добавить ваш запрос ?
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35654214
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv> union all
> SELECT *
> FROM Tovar_history
> WHERE DateStart IS NULL and DateEnd IS NULL
>
> и приплыли...
Куда приплыли-то? Чем вам это не нравится, даже если добавить ваш запрос ?
Например, Оракл не хранит в индексе те записи, у которых все поля в составе этого индекса IS NULL. Т.е. ни индекс (DateStart, DateEnd), ни индекс (DateEnd, DateStart) здесь не помогут. Можно, конечно, добавить третье поле, которое всегда NOT NULL, или на базе фукнции NVL сделать FBI-индекс.
Но это решение уже
а) обретает привязку к СУБД
б) требует преобразования запроса, что не всегда возможно.
в) реальный запрос может быть намного сложнее и это преобразование может сильно испортить его производительность.
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35655210
Bely
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bogdanov AndreyBelyВсетаки, для первого запроса надо использовать аналитические функции.Лучше не надо :)ну, для конкретно этого запрос - да, запрос без аналитики будет лучше.

ЗЫ: статистику по индексу тоже неплохо бы пересобирать :)
может тогда FTS и не будет
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35655400
Kirill Razuvaev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>> Пересечений быть не должно разрывы могут. Товар может какое-то время
>> отсутствовать
>> по разным причинам на предприятии, на это время нужно прекратить вести
>> историю,
>> после появления товара историю нужно продолжить с даты появления.
Мне кажется, стоит отделить мух от котлет.
История товара, по-моему - это история изменения его характеристик, цвета,
размера, единицы измерения, наименования и т.п.
Наличие и отсутствие - это история ДВИЖЕНИЯ товара. Характеризоваться оно
должно наличием или отсутствием его - т.е. количественной единицей.
Т.е. в Вашем случае либо не совсем корректный пример, либо стоит
скорректировать схему данных. Тогда и разрывов не будет.
Историю гораздо проще и НАДЕЖНЕЕ хранить с одной датой, т.к. поиск значения
на определенную дату легко реализуется в запросе, причем выполняет его
сервер не напрягаясь (при правильной индексации).
В предложенном Вами втором варианте есть два опасных момента:
- возможность появления разрывов с неопределенными значениями параметров
- потенциальные сложности при поиске значения
Код: plaintext
1.
select Name from 
Tovar_history where MyDate between DateStart and DateEnd
- разные
сервера могут по-разному использовать или даже НЕ использовать индексы по
этим полям.
- необходимость корректировки неограниченного количества "соседних" записей
для обеспечения непересечения и неразрывности. Ведь может потребоваться
модифицировать не одну, а несколько записей, а какие-то из них могут вообще
оказаться некорректными (целиком внутри диапазона новой записи). велики
шансы тут мертвую петлю схватить...


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

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

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

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

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

В общем, не вижу я тут ничего страшного.
Полно у нас таких запросов, ничего, работают. (правда, не на оракле)
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
История одна дата vs две. Что лучше?
    #35656000
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kirill Razuvaev пишет:

> Мне кажется, стоит отделить мух от котлет.
> История товара, по-моему - это история изменения его характеристик, цвета,
> размера, единицы измерения, наименования и т.п.

Вообще, это --- вопрос предметной области. Вы её хотите обсуждать ещё ?
Чел. сказал, что один товар заменяется на другой - значит заменяется.
Нет- его дело, у него в таблице будет не товар, а свойство товара,
всё остальное останется так же, для проблемы это принципиального
значения не имеет.

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

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

ЧТо за волшебный такой запрос, уже второй раз его в топике вижу.

Это же

SELECT kod FROM hist t1
WHERE t1.dt = (SELECT max(t2.dt) FROM hist t2
WHERE t2.dt < sysdate - 1000);
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
25 сообщений из 129, страница 2 из 6
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / История одна дата vs две. Что лучше?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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