Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » InterBase и FireBird: вопросы по работе и их решение

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 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

Открыть новую тему     Написать ответ в эту тему

delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
AlexPetrovich
Готовы некоторые теоретические итоги по теме индексов.  
 

Цитата:
По моему пытаться делать оптимизацию изобретая нестандартные SQL - это путь в никуда.  

Нет. Я пытаюсь изобрести стандартные сервера SQL. Пример - в экспериментах над крысами выяснилось что если приучить крысу нажимать рычажок чтобы крыса получала сыр, то потом если крыса хочет удовольствия она будет жать рычажок всегда, даже если не получает уже сыр и такая крыса может умереть с голоду. Мне не очень приятно чуствовать себя крысой и ничего не получать нажимая всякие кнопки. Путь крысы - путь в никуда.  
 
Из предыдущих примеров видно что сервер выбрал себе модель поведения с индексами, но существует и другая модель. И так. Сервер считает справедливым использовать все индексы которые он обнаружит в условии:
 
>where a between 1 and 2    
> b between 1 and 20000000000
> c between 1 and 20000000000
...
> z between 1 and 20000000000
 
То есть все индексы которые имеются - являются полезными именно для этого запроса и индексы обязаны быть использованными именно для полных вычислений каждого подусловия. Вру, - сервер считает что любой индекс одинакого полезен в качестве первого берущегося для последовательного чтения. То что я вру было проверено - меняем местами индексы в плане и запрос становится быстрее. Во первых следует заметить что индексы используются эффективно для локейтов (сортированного поиска) и так же для последовательного чтения когда известно заране что диапазон чтения будет всегда меньше чем количество данных в таблице.
 
В примере between 1 and 20000000000, но данных там точно between 10 and 20000000. И с какого тогда перепугу сервер делает вывод что индексы которые безумно полезны в других запросах так же полезны именно в этом запросе? А он делает этот вывод потому что в S Q L нет возможности указать серверу что его модель поведения является неуместной.
 
Есть другая модель, это абсолютно не касается и не ломает планы по использованию индексов. По этой модели поведения для последовательных чтений используется только 1 индекс и он указан в запросе. Остальные индексы используются для локейтов поиска. При последовательном чтении первого индекса все остальные условия вычисляются только исходя из математики выражения только для фильтрации. Это другая модель поведения сервера по отношению к индексам. Такая модель поведения является вполне справедливой для запросов в которых участвуют связи между двумя таблицами, которые являются огромными а количество данных возвращаемых запросом всегда будет маленьким из за того что ПО НЕПОНЯТНЫМ ПРИЧИНАМ ПРОГРАММИСТУ ИЗВЕСТНО ЕДИНСТВЕННОЕ ПОДУСЛОВИЕ ЗАПРОСА ФИЛЬРУЮЩЕЕ ДАННЫЕ МАКСИМАЛЬНО.
Мне думается ему известно это условие в 100% запросов которые он пишет, и во всех 100% его знания запроса являются бесполезными. Если он получает ещё и удовольствие, то он точно крыса...
 

Цитата:
По моему пытаться делать оптимизацию изобретая нестандартные SQL - это путь в никуда.  

100% случаев стандартные SQL не даёт использовать мои знания тех данных с которыми он работает. Пользоваться таким SQL - путь в никуда. Вернее сервер вполне может мне помочь в 50% запросов, но только при использовании планов либо +0. То что существует +0 говорит о том что не мне одному приходится отключать конкретные индексы. Но эта возможность просто припарка, которая не позволяет реально выбрать другую модель отношения к индексам.
 
2) В случае когда я пишу слева на право сверху вниз запрос SQL мне удобнее определить первичный индекс до того как я начну писать джойны

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 08:22 08-06-2012 | Исправлено: delover, 00:42 27-07-2012
AnGo



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
OFFTOP
Не иначе танка прокачал!  
 

Цитата:
2) В случае когда я пишу слева на право сверху вниз запрос SQL мне удобнее определить первичный индекс до того как я начну писать джойны

Тогда такая форма будет неполиткоррекна по отношению к пишущим справа налево и снизу вверх. А японцы те вааще пишут в столбик!

Всего записей: 1078 | Зарегистр. 07-07-2002 | Отправлено: 16:54 08-06-2012
ekemov

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Подскажите как подружить FireBird 2,5 х64  с базой которая сделана была в версии 1,5. При попытке подключиться к ней, пишет что не верный формат сток.

Всего записей: 804 | Зарегистр. 23-12-2005 | Отправлено: 18:02 09-06-2012
ant0ni02004

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ekemov
нужно сделать backup в версии 1.5 и restore уже в новой, 2.5 версии

Всего записей: 442 | Зарегистр. 26-10-2004 | Отправлено: 22:23 09-06-2012
miwa

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ekemov
Если в базе данных были русские комментарии или названия объектов, тогда  первый рестор нужно делать с опцией -fix_fss_metadata.
 
А вообще ODS от 1.5 к 2.5 настолько поменялась, что база может на 2.5 и не заработать с ходу.

Всего записей: 455 | Зарегистр. 10-10-2004 | Отправлено: 16:36 10-06-2012
ant0ni02004

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ekemov
miwa
это да, возможно в 1.5 придётся перед бэкапом кое-что закоментить в триггерах и процедурах, чтоб нормально восстановилось, а потом уже в 2.5 допиливать с учетом нового синтаксиса

Всего записей: 442 | Зарегистр. 26-10-2004 | Отправлено: 17:58 10-06-2012
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
AnGo

Цитата:
Тогда такая форма будет неполиткоррекна по отношению к пишущим справа налево и снизу вверх.  

Возможно и я выражаю мысль не политкоректно. Сервер совершенно точно знает что индекс для последовательного чтения и индекс для поиска (например уникальный индекс при джойне) это разные индексы. Если для поиска уникального значения не важен порядок филдов в индексе, главное чтобы они были перечислены первыми. То для оптимизации ORDERBY вычисляется индекс для последовательного чтения! Сервер это отлично знает.
Для своего примера я сделал смелое предположение что сервер FB найдёт оптимальный индекс для последовательного чтения. Не тут то было...
Вот индекс:

Код:
CREATE INDEX TABLE1_IDX3 ON TABLE1 (PARENT_ID, GRADE_ID);

 
Вот выборка для которой этот индекс действительно оптимален:

Код:
select * from
table1 t1
where
  t1.parent_id between 1 and 1
order by
  t4.parent_id, t4.grade_id

 
Вот автоматический план:

Код:
PLAN (T4 ORDER TABLE1_IDX3 INDEX (TABLE1_IDX2))

 
Сервер в упор не увидел что TABLE1_IDX3 оптимален для последовательного чтения.
По моей вводимой модели сервер должен знать что оптимальный индекс для последовательного чтения выделен пользователем. То есть подходит любой индекс начинающийся с условия пользователя. Если найден индекс подходящий пользователю + содержащий в себе  условие ORDERBY, то он должен ОБЯЗАН ПО МОЕЙ МОДЕЛИ выбрать именно TABLE1_IDX3. +0 тут уже не канает, только через составление правильного плана можно заставить его использовать.
 
ЗЫ
Я бы написал свой препроцессор SQL который генерит такие планы, но это будет только для запросов на стороне клиента, а в хранимые процедуры я не могу засунуть свои знания запроса. А у сервера уже всё готово для этого - отсюда недовольство текущим положением. Рядом с ORDERBY не стояло условие последовательного чтения. Хотя для перехода от TABLE1_IDX2 до TABLE1_IDX3 теряются практически наносекунды, всё равно они теряются. Вот примерный код который нужен для состыковки индексов:

Код:
function TIndexList.IndexOf(RecNo: Integer): Integer; assembler;
const
  FListPtr  = 4;
  FCountPtr = 8;
asm
        PUSH    EDI
        PUSH    ECX
        MOV     EAX,Self
        MOV     EDI,[EAX].FListPtr
        MOV     ECX,[EAX].FCountPtr
        PUSH    ECX
        MOV     EAX,RecNo
        REPNE   SCASD
        POP     EAX
        JE      @@1
        OR      EAX,-1
        JMP     @@2
@@1:    SUB     EAX,ECX
        DEC     EAX
@@2:    POP     ECX
        POP     EDI
end;

Мои тесты показывают, что эта операция на индексах очень быстрая (Индексы тут 4х байтные). На каждый RecNo выборки должна произойти подобная операция. Ну и зачем она Вам?..
 
 
 
Добавлено:
Теперь о небывалом ускорении, которое увы не доступно потому что сервер вынужденно Вас игнорит.
 
Пример:

Код:
select * from
table1 t4
where
  t4.parent_id in (3,2,1,8)
order by
  t4.grade_id

 
Все вполне справедливо:

Код:
PLAN (T4 ORDER TABLE1_IDX1 INDEX (TABLE1_IDX2, TABLE1_IDX2, TABLE1_IDX2, TABLE1_IDX2))

Юзал индекс для каждого элемента по отдельности. Это всё вполне справедливо, но медленно.  
 
Если я напишу:

Код:
select * from
table1 t4
on
  (t4.parent_id in (3,2,1,8))
order by
  t4.grade_id

То можно предположить что я это делаю сознательно. У элементов in есть максимальное и минимальное значение - это between 1 and 8. Индекс будет использован не 4 раза а всего 1 раз. Представим 20 элементов идущих сподряд в таблице с 5 миллионами записей. Это будет 20 раз использование 5и миллионного индекса. Я конечно могу представить пользователя который засунет туда in (3,2,1,4000000), но вет сервер не может быть виноват, что существуют глупые запросы? Но именно по этой причине Вам недоступно вполне реальное ускорение запроса уже не в сотни а в тысячи раз...

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 12:21 11-06-2012 | Исправлено: delover, 00:47 27-07-2012
ekemov

Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
НЕ очень удобно будет. Просто иногда необходимо просмотреть данные в базе. А 1,5 на х64 системе не работает. А ради 1,5 версии ХР держать уже смысла нету.

Всего записей: 804 | Зарегистр. 23-12-2005 | Отправлено: 07:48 12-06-2012
miwa

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover
 
Можно попросить вас не пиарить мсскл, мсклауд и другие не менее нужные мс-штуки, прописывая на них ссылки в каждом предложении? Я конечно понимаю, черный СЕО, бешеные деньги и все такое, но давайте на минутку предположим, что мы на техническом форуме, пользователи которого а) не глупее вас и б) расчитывают увидеть по ссылкам полезную информацию, относящуюся к рассматриваемой теме.
 
Ну и заодно - в теме о IB/FB давайте писать именно об IB/FB, а не о вашем виденье того, как надо развиваться системам управления базами данных?

Всего записей: 455 | Зарегистр. 10-10-2004 | Отправлено: 08:59 12-06-2012
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Если я правильно понял ekemov, то он действительно прав, так как про оператор IN, я не стал сразу разжевывать. Предлагаю посчитать затраты на ресторацию стандартного порядка возвращаемых оператором IN записей. При моём последовательном чтении нам кажется что сервер вернёт отсортированные айдишники, а не тот порядок который указан в скобках - иногда это не удобно. По этой причине посчитаем затраты на ресторацию этого порядка от самого лёгкого случая до самого тяжелого.  
1) Случай когда в запросе уже есть ORDERBY нам не следует вообще делать ресторацию. Тут всё ясно.
2) Случай когда последовательное чтение идёт именно по айдишникам, то есть по уникальному индексу. Это случай когда для ресторации требуется ещё один массив - буфер выборки равный по количеству элементов массиву который в скобках. Когда запись является отобранной она должна ложится на против своего значения. Это IndexOf для каждой записи - то есть наносекунды. Это более 90% случаев использования IN. Из этих 90% половина содержит ORDERBY.
3) Случай. Во первых он отличается тем что количество элементов IN более 2500. Это значит в скобках будет хранимая процедура, иначе вам не передать такое количество элементов в запрос. Мы будем передавать 60 тысяч элементов через селект из хранимой процедуры. Естественно, в нашем случае сервер обязан сделать фечьол хранимой процедуры чтобы выяснить мин-макс элементы, далее всё ничем не отличается. Но в нашем случае мы последовательно читаем по не уникальному индексу. Следовательно тот буфер выборки отличается по размеру от того что возвращает селект хранимой процедуры. Следовательно ресторация обязана использовать сортированную вставку. При сортированной вставке используется операция сравнения. Эта операция похожа на переделанный IndexOf. Он должен вернуть один из двух элементов который встретится первым, он и будет минимальным. Сама эта процедура занимает наносекунды, но весь процесс сортированной вставки может занять время равное 1/24. Человеческий глаз замечает 24 кадра в секунду, 1/24 это 42 миллисекунды на ресторацию.
 
Я хочу рассмотреть последний случай - без сортировки по неуникальному индексу для значений которые имеют тип строка. Мы выбираем 60 тысяч записей в 5и милионной таблице. Мои затраты на всё это хозяйство занимают примерно 100 миллисекунд. Это два кадра для человеческого глаза. Современные затраты сервера в среднем превысят 5 минут (не проверял, ИМХО за это не бейте, боюсь что может быть и дольше). Для людей чувствительных ко времени вполне видна разница, нечуствительные могут продолжать наслаждаться тормозами. Теперь:

Цитата:
Просто иногда необходимо просмотреть данные в базе.

Да это один из случаев когда я использую оператор IN.
 
Второй случай, например, моя таблица имеет 5 миллионов документов. В программе пользователь видит только документы за последний год, почти всегда. Чутьё мне подсказывает что айдишники этих документов генерятся последовательно - в основном. Моя задача только в том, что если пользователь нажал CTRL+A и выделил все документы, а потом исключил из выборки те которые не стоят на учёте. То моя задача показать общую сумму по всем документам. Для этого я делаю в запросе оператор IN. По моей схеме пользователь даже не заметит что сумму считает не моё приложение, а сам сервер. В нынешнем случае, если сервер будет делать эту операцию то пользователь будет психовать каждый день. И так мои 100 миллисикунд против сегодняшних 5 минут на каждый чих...
 
Было бы приятно, если бы сервер умел и это тоже делать.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 09:09 12-06-2012
salexn1



Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
miwa
Если вы о линках - то это как-то само получается
Попробуйте набрать ключевые( оптимальный сервер ) слова и вы сможете создать пост из одних "линок"

Всего записей: 502 | Зарегистр. 21-02-2008 | Отправлено: 09:17 12-06-2012
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
AnGo

Цитата:
Тогда такая форма будет неполиткоррекна по отношению к пишущим справа налево и снизу вверх. А японцы те вааще пишут в столбик!  

На сколько я слышал от гакусеев (студенты по японски), они пишут сверху в низ, так что их мнение по этому вопросу скорее всего совпадёт с моим мнением.
 
Добавлено:
В продолжение Теперь о небывалом ускорении.
Последний случай который я описывал настолько экстравагантный, что я бы в принципе мог бы не делать ресторацию порядка элементов IN (с помощью сортированной вставки). Но такой SELECT может быть использован в конструкции INSERT from SELECT. И мне было бы понятно желание тех кто хотел бы управлять порядком вставки, вполне разумное желание занимающее очень мало времени.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 09:38 12-06-2012 | Исправлено: delover, 10:05 12-06-2012
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Естественно, что выделение из множества условий, условия подходящего для последовательного чтения индекса является квантором. Для такого квантора подходят операции с промежутком (и операции равенства, как частный случай промежутка), то есть операторы = between и IN. Большего я пока не придумал, операции < > рискованно использовать в моей схеме, хотя это тоже некие промежутки. В любом случае для <> это +1 поиск по индексу и мы получаем % занимаемого промежутка. В этом случае можно выбирать схему, но тогда придётся делать поиск до составления плана индексов. Ну или полностью довериться пользователю в этом вопросе, как вариант.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 11:43 12-06-2012 | Исправлено: delover, 11:45 12-06-2012
salexn1



Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover
Имхо, у вас диалог самим с собой...

Всего записей: 502 | Зарегистр. 21-02-2008 | Отправлено: 12:08 12-06-2012
miwa

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
salexn1
Мне кажется, это... кхм... мыслеизлияние даже диалогом называть - слишком громко. То ли человек переучился и из него тепер прут слова без какого-либо смысла, то ли он так стебется, то ли бредогенератор тестирует

Всего записей: 455 | Зарегистр. 10-10-2004 | Отправлено: 14:20 12-06-2012
ant0ni02004

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover
насколько я знаю, IN всё равно преобразовывается в OR

Всего записей: 442 | Зарегистр. 26-10-2004 | Отправлено: 15:43 12-06-2012
salexn1



Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
miwa
ну отчего же поговорить с хорошим человеком - самим с собой
к тому же он сам себя хорошо понимает

Всего записей: 502 | Зарегистр. 21-02-2008 | Отправлено: 15:45 12-06-2012
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
salexn1
miwa
ant0ni02004
Двоешники. Я вам толдычу что такое индекс - я то думаю со своим топорным мозгом и бедным запасом алгоритмов вызову другую реакцию. Понимаю Вы не видели индексы под отладчиком по этому для Вас это страшный зверь. Уверяю он не страшный.  
 
Пример данных с индексами без любых компонентов баз данных. Под отладчиком можно даже руками потрогать 2 разные операции по использованию индексов. Скорее автор этой библиотеки сам с собой разговаривал.
 

Код:
uses vdb;
 
//...
 
procedure TForm1.Button1Click(Sender: TObject);
var
  v: TVariantArray;
  idx: TIndexList;
  colors: TStrings;
  i: Integer;
begin
  //Заполнение
  v.Init('name=ftString,16'#13#10'color=ftInteger');
  colors := vTableStorage.GetColorIdentsStrings;
  for i := 0 to colors.Count - 1 do
  begin
    v.Append;
    v['name'] := colors[i];
    v['color'] := TColor(colors.Objects[i]);
  end;
  colors.Free;
  v.Sort('color');
 
  //Создание индекса
  idx := TIndexList.Create(@v, 'name');
  v.AddIndex(idx);
  idx.Eval;
 
  ShowMessage('Последовательность данных');
  v.First;
  for i := 1 to 5 do
  begin
    ShowMessageFmt('%d) %s', [i, v['name']]);
    v.Next;
  end;
 
  //Первая операция - использование индекса при селекте
  ShowMessage('Последовательное чтение индекса');
  for i := 1 to 5 do
  begin
    v.RecNo := idx[i-1];
    ShowMessageFmt('%d) %s', [i, v['name']]);
  end;
 
  //Вторая операция - поиск по индексу - lookup,locate,locateNext
  ShowMessage('Поиск с использованием индекса');
  ShowMessage(v.Lookup('name', 'Red', 'name'));
 
  //Финализация
  v.DoneIndexes;
  v.Done;
end;

 
адрес библиотеки vdb.pas
http://cc.embarcadero.com/item/28790
или
https://sourceforge.net/p/vdbi/home/Home/

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 21:46 12-06-2012 | Исправлено: delover, 07:52 13-06-2012
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Программист, который посмотрит на индексы под отладчиком и поймёт что это 2 - две разные операции с использованием индексов, который потом перечитает что я писал по этому поводу. Тот программист не увидит ничего сверхестественного в том что было написано в топике. А так же поймёт что индексы используются сервером неэффективно только из-за неграмотности со стороны клиента. Клиент (со своими потребностями) достоен своего "правительства" тоесть - сервера.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 08:27 13-06-2012
ant0ni02004

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover

Цитата:
адрес библиотеки vdb.pas
 
для этой конкретной реализации(библиотеки), так наверное всё и есть, допустим...
осталось только понять, какое это имеет отношение конкретно к Firebird/Interbase и их индексам?
 
а что касается эффективности - есть такое дело, иногда приходится переписывать запросы, пока сервак не начнёт применять нужные сортировки/слияния и в правильном порядке. так и Firebird не Oracle, который умеет находить этот порядок почти всегда

Всего записей: 442 | Зарегистр. 26-10-2004 | Отправлено: 16:26 13-06-2012 | Исправлено: ant0ni02004, 16:27 13-06-2012
Открыть новую тему     Написать ответ в эту тему

Страницы: 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

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » InterBase и FireBird: вопросы по работе и их решение


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru