powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Индекс на дату (Sybase ASA)
25 сообщений из 32, страница 1 из 2
Индекс на дату (Sybase ASA)
    #36564939
pit_birn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всех приветствую.
Существует следующая проблема:

Сервер: Sybase ASA 9.0.2.3402

Таблица:
Код: plaintext
1.
2.
3.
4.
5.
6.
CREATE TABLE "Owner"."Znach" (
	"id" INTEGER NOT NULL,
	"Dogovor" VARCHAR( 20 ) NULL,
        ****** много-много других полей
	"DteIndex" DATE NULL
);

Таблица ~2.5 млн. записей.

Создаем индекс:
Код: plaintext
create index aaa on Owner.Znach(DteIndex)

Пишем запрос (отбираем количество записей за 2 дня):
Код: plaintext
1.
2.
select count(*) from owner.znach
where (dteindex>='2009-12-01') and (dteindex<'2009-12-03')
Count(*) = 16098
Execution time: 0.047 seconds

Через графический GET PLAN показывает что Index Scan (aaa)

Пишем запрос (отбираем количество записей за 4 дня):
Код: plaintext
1.
2.
select count(*) from owner.znach
where (dteindex>='2009-12-01') and (dteindex<'2009-12-05')
Count(*) = 34199
Execution time: 13.266 seconds

Через графический GET PLAN показывает что Table Scan.

Кто скажет в чем проблема?
Почему при поиске двух дней использует индекс, а при четырех днях делает уже поиск по всей милионной таблице?
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36565010
iLLer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pit_birn,

Вот читайте и наслаждайтесь:
И еще один глюк в АСА, теперь и в 9.02.3044
Только внимательно, особенно про convert...
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36565315
pit_birn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Так какой выход?
Создавать фиктивное поле куда переводить дату в целочисленное число и по нему делать поиск?
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36565385
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pit_birn wrote:

> Кто скажет в чем проблема?
> Почему при поиске двух дней использует индекс, а при четырех днях делает
> уже поиск по всей милионной таблице?

Так ты познакомился с COST-based оптимизатором ...
И его глюками.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36565422
iLLer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pit_birn,
Это вторая проблема, которая может встретится.
Ваша, судя по этому , может решится несколькими способами:
1) перестройкой статистики
2) в явном виде указать серверу в условии convert(date,'тут нужная дата') вместо 'тут нужная дата'
3) в явном виде говорить серверу брать индекс: force index()
4) если, не поможет, есть путь уходить от даты в таких таблицах. Там действительно существуют какие-то скрытые гири, связанные с работой индексов. После того, я везде стал использовать поля smallint|integer. Все работает железно и предсказуемо.
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36565520
pit_birn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
1.
Код: plaintext
CREATE STATISTICS Owner.Znach
Execution time: 38.797 seconds

Код: plaintext
1.
select count(*) from owner.znach
where (dteindex>='2009-12-01') and (dteindex<'2009-12-05')
Execution time: 13.375 seconds

2.

Код: plaintext
1.
select count(*) from owner.znach
where (dteindex>=convert(date,'2009-12-01')) and (dteindex<convert(date,'2009-12-05'))
Execution time: 14.781 seconds

3.
Код: plaintext
1.
select count(*) from owner.znach (index aab)
where (dteindex>=convert(date,'2009-12-01')) and (dteindex<convert(date,'2009-12-05'))
Execution time: 13.422 seconds

Не помогло. Или опять что-то не так делаю?
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566087
Фотография Ggg_old
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
без планов выполнения запросов что-то сложно сказать.
Попробуйте еще и такой вариант:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
BEGIN 
declare @d1 date;
declare @d2 date;
set d1=convert(date,'2009-12-01');
set d2=convert(date,'2009-12-05');
select count(*) from owner.znach
where dteindex>=@d1 and dteindex<@d2;
END
И этот жа вариант но с хинтом на индекс в запросе.
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566101
iLLer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Надо бы не на время выполнения глядеть, а на план. И второе, неочевидный синтаксис, вроде как with(index(...)) должно быть.
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566169
pit_birn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Как выводить текстовый план запроса?
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566216
pit_birn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
BEGIN 
declare @d1 integer;
declare @d2 integer;
set @d1=convert(date,'2010-03-01');
set @d2=convert(date,'2010-04-01');
SELECT PLAN('select count(*) from owner.Opers1
where dteindex>=@d1 and dteindex<@d2');
END

( Plan [ Total Cost Estimate: 49.151023 ] ( SingleRowGroupBy ( TableScan Opers1[ ( 20100301 <= Opers1.DteIndex < 20100401 ) : 19.35133284% Statistics ] ) ))

Код: plaintext
1.
2.
3.
4.
5.
6.
BEGIN 
declare @d1 date;
declare @d2 date;
set @d1=convert(date,'2009-12-01');
set @d2=convert(date,'2009-12-05');
select count(*) from owner.opers1 with (index (dteindex1)) where dteindex>=@d1 and dteindex<@d2;
END

( Plan [ Total Cost Estimate: 1831.714457 ] ( SingleRowGroupBy ( IndexScan Opers1 dteindex1 ) ))
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566218
pit_birn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Что же ASA даже целочисленные индексы чтоли не умеет брать?

Или может какие-то настройки сервера есть по размеру кэша у индекса или еще что-то подобное?
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566240
Dim2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
07.04.2010 16:32, pit_birn пишет:

> Что же ASA даже целочисленные индексы чтоли не умеет брать?

Не считай сервер глупее себя.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566276
Фотография Alexandr Nikolaev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Какие планы получаться если выполнить
Код: plaintext
1.
2.
3.
4.
5.
BEGIN
  drop statistics on owner.opers1(dteindex);
  select PLAN('select count(*) from owner.Opers1 where dteindex >= ''2010-03-01'' and dteindex < ''2010-03-01''');
  select PLAN('select count(*) from owner.Opers1 where dteindex >= ''2009-12-01'' and dteindex < ''2009-12-05''');
END
?
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566355
pit_birn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
У меня поле dteindex - теперь целочисленное.

Запустил без кавычек.
Код: plaintext
1.
2.
3.
4.
BEGIN
  drop statistics on owner.opers1(dteindex);
  select PLAN('select count(*) from owner.Opers1 where dteindex >= 20100301 and dteindex < 20100301');
  select PLAN('select count(*) from owner.Opers1 where dteindex >= 20091201 and dteindex < 20091205');
END

1ый: ( Plan [ Total Cost Estimate: .000001 ] ( SingleRowGroupBy ( PreFilter [ FALSE ] ( TableScan Opers1 ) ) ))
2ой: ( Plan [ Total Cost Estimate: .0900045902 ] ( SingleRowGroupBy ( IndexScan Opers1 dteindex1 ) ))
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566364
Фотография Ggg_old
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну теперь все ясно:
там где нет хинта сервер оценил, что в запрос попадет 19.35133284% всех данных. 20% от таблицы это однозначно выбор за table scan. Если 20% - это правда и сервер неошибся при оценивании статистики, то план правильный. Если нет, то надо обновить статистику и повторить запрос.
Обратите внимание на оценку стоимости зпросов с индексом: 1831.714457 и без индекса: 49.151023
Ежу ясно, что сканирование дешевле. В общем все упирается в статистику, верна она или нет.
Можно даже без перестройки статистики проверить запросом:
Код: plaintext
1.
2.
3.
4.
declare ....
set a1=count(*) from owner.Opers1 where dteindex>=@d1 and dteindex<@d2;
set a2=count(*) from owner.Opers1;
select (a1* 100 /a2) as probability;
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566391
pit_birn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
BEGIN
declare @a1 integer;
declare @a2 integer;
declare @d1 integer;
declare @d2 integer;
set @d1=convert(date,'2010-03-01');
set @d2=convert(date,'2010-04-01');
select count(*) into @a1 from owner.Opers1 where dteindex>=@d1 and dteindex<@d2;
select count(*) into @a2 from owner.Opers1;
select @a1,@a2,((@a1* 100 )/@a2) as probability;
END

@a1=224149
@a2=1158308
probability=19
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566406
pit_birn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Т.е. в подобных ситуациях нужно "насильно" указывать в запросах использование индекса?
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566440
Фотография Ggg_old
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2pit_birn что и требовалось доказать. статистика верна и сервер в общем правильно выбрал план.
Осталось выяснить так ли это на самом деле.
- Какое время выполнения запроса с хинтом на индекс и без него?

Если не хочется хинтовать то можно поиграться с такими параметрами:
Код: plaintext
1.
2.
3.
4.
5.
optimization_goal option [database]
Allowed values 
First-row, All-rows
Default 
All-rows
и
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
optimization_level option [database]
Controls the amount of effort made by the SQL Anywhere query optimizer to find an access plan for a SQL statement.

Allowed values 
 0 - 15 

Default 
 9 


...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566449
Фотография Ggg_old
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а для общего развития стоит покурить весь раздел в документации: Query Optimization and Execution
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566478
pit_birn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
3.
BEGIN
  drop statistics on owner.opers1(dteindex);
  select PLAN('select count(*) from owner.Opers1 where dteindex >= 20100101 and dteindex < 20100105');
END

( Plan [ Total Cost Estimate: 41.63739025 ] ( SingleRowGroupBy ( TableScan Opers1[ ( 20100101 <= Opers1.DteIndex < 20100105 ) : 2.258879392% Index ] ) ))

Тогда вот эта ситуация не ясна. Почему при 2.25% он использует TableScan?
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566516
Фотография Ggg_old
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вы зачем статистику дропнули? Как работает оптимизатор при полностью отсутсвующей статистике я точно не знаю. Помню, что в sybase asa 5.5 оптимизатор был не cost-based а rule-based. Это означало, что статистику сервер оценивал не исходя из реальноuj распределения данных, а исходя из применямых операций сравнения в where. Если стояло =, то считалсь, что захватывается малый процент строк и надо было стремиться взять индекс. А если были фильтры по <,> то считалось, что захватывается большой процент строк и надо сканирование.
Так что вы статистику верните обратно и повторите запрос на действительно маленьком интервале дат.
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566532
Фотография Ggg_old
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выдержка из документации:

The DROP STATISTICS statement deletes all internal statistical data from the ISYSCOLSTAT system table for the specified columns. This drastic step leaves the optimizer with no access to essential statistical information. Without these statistics, the optimizer can generate very inefficient data access plans , causing poor database performance.
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566593
pit_birn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
CREATE STATISTICS Owner.Opers1;
create statistics on owner.opers1(dteindex);

Код: plaintext
1.
2.
3.
begin
select PLAN('select count(*) from owner.Opers1 where dteindex >= 20100101 and dteindex < 20100110');
select PLAN('select count(*) from owner.Opers1 where dteindex >= 20100101 and dteindex < 20100115');
end

1ый: ( Plan [ Total Cost Estimate: 60.68097175 ] ( SingleRowGroupBy ( IndexScan Opers1 dteindex1 ) ))
2ой:( Plan [ Total Cost Estimate: 105.9351135 ] ( SingleRowGroupBy ( TableScan Opers1[ ( 20100101 <= Opers1.DteIndex < 20100115 ) : 8.063234049% Statistics ] ) ))
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566799
Фотография Ggg_old
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну а время выполнения какое с индексом и без него? Если без индекса быстрее, то чего париться то? В последнем запросе у вас попадает в выборку 8% данных, что не мало и скан вполне рабочее решение. Сложность оптимиатора состоит не в том, что-бы индекс вставить, а что-бы затратить минимум ресурсов на выполнение запроса.
...
Рейтинг: 0 / 0
Индекс на дату (Sybase ASA)
    #36566819
pit_birn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
select count(*) from owner.Opers1 where dteindex >=  20100101  and dteindex <  20100115 
Execution time: 4.016 seconds

Код: plaintext
select count(*) from owner.Opers1 with (index (dteindex1)) where dteindex >=  20100101  and dteindex <  20100115 
Execution time: 0.781 seconds
...
Рейтинг: 0 / 0
25 сообщений из 32, страница 1 из 2
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Индекс на дату (Sybase ASA)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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