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

Сервер: 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
07.04.2010, 10:29
    #36565010
iLLer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
pit_birn,

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

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

Так ты познакомился с COST-based оптимизатором ...
И его глюками.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
07.04.2010, 12:15
    #36565422
iLLer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
pit_birn,
Это вторая проблема, которая может встретится.
Ваша, судя по этому , может решится несколькими способами:
1) перестройкой статистики
2) в явном виде указать серверу в условии convert(date,'тут нужная дата') вместо 'тут нужная дата'
3) в явном виде говорить серверу брать индекс: force index()
4) если, не поможет, есть путь уходить от даты в таких таблицах. Там действительно существуют какие-то скрытые гири, связанные с работой индексов. После того, я везде стал использовать поля smallint|integer. Все работает железно и предсказуемо.
...
Рейтинг: 0 / 0
07.04.2010, 12:35
    #36565520
pit_birn
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
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
07.04.2010, 14:53
    #36566087
Ggg_old
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
без планов выполнения запросов что-то сложно сказать.
Попробуйте еще и такой вариант:
Код: 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
07.04.2010, 14:54
    #36566101
iLLer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
Надо бы не на время выполнения глядеть, а на план. И второе, неочевидный синтаксис, вроде как with(index(...)) должно быть.
...
Рейтинг: 0 / 0
07.04.2010, 15:18
    #36566169
pit_birn
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
Как выводить текстовый план запроса?
...
Рейтинг: 0 / 0
07.04.2010, 15:32
    #36566216
pit_birn
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
Код: 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
07.04.2010, 15:32
    #36566218
pit_birn
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
Что же ASA даже целочисленные индексы чтоли не умеет брать?

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

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

Не считай сервер глупее себя.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
07.04.2010, 15:49
    #36566276
Alexandr Nikolaev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
Какие планы получаться если выполнить
Код: 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
07.04.2010, 16:07
    #36566355
pit_birn
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
У меня поле 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
07.04.2010, 16:09
    #36566364
Ggg_old
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
ну теперь все ясно:
там где нет хинта сервер оценил, что в запрос попадет 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
07.04.2010, 16:15
    #36566391
pit_birn
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
Код: 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
07.04.2010, 16:20
    #36566406
pit_birn
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
Т.е. в подобных ситуациях нужно "насильно" указывать в запросах использование индекса?
...
Рейтинг: 0 / 0
07.04.2010, 16:28
    #36566440
Ggg_old
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
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
07.04.2010, 16:31
    #36566449
Ggg_old
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
а для общего развития стоит покурить весь раздел в документации: Query Optimization and Execution
...
Рейтинг: 0 / 0
07.04.2010, 16:38
    #36566478
pit_birn
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
Код: 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
07.04.2010, 16:48
    #36566516
Ggg_old
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
А вы зачем статистику дропнули? Как работает оптимизатор при полностью отсутсвующей статистике я точно не знаю. Помню, что в sybase asa 5.5 оптимизатор был не cost-based а rule-based. Это означало, что статистику сервер оценивал не исходя из реальноuj распределения данных, а исходя из применямых операций сравнения в where. Если стояло =, то считалсь, что захватывается малый процент строк и надо было стремиться взять индекс. А если были фильтры по <,> то считалось, что захватывается большой процент строк и надо сканирование.
Так что вы статистику верните обратно и повторите запрос на действительно маленьком интервале дат.
...
Рейтинг: 0 / 0
07.04.2010, 16:50
    #36566532
Ggg_old
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
Выдержка из документации:

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
07.04.2010, 17:10
    #36566593
pit_birn
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
Код: 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
07.04.2010, 18:13
    #36566799
Ggg_old
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
Ну а время выполнения какое с индексом и без него? Если без индекса быстрее, то чего париться то? В последнем запросе у вас попадает в выборку 8% данных, что не мало и скан вполне рабочее решение. Сложность оптимиатора состоит не в том, что-бы индекс вставить, а что-бы затратить минимум ресурсов на выполнение запроса.
...
Рейтинг: 0 / 0
07.04.2010, 18:21
    #36566819
pit_birn
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс на дату (Sybase ASA)
Код: 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
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Индекс на дату (Sybase ASA) / 25 сообщений из 32, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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