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

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в 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

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

SERGE_BLIZNUK

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

Цитата:
И кстати - откройте для себя хинты.

AlexPetrovich, а можно чуть-чуть "разжевать" - объяснить для тех, "кто в танке" (я себя имею в виду сейчас, если что... :) ), что за хинты имеются в виду?!

Всего записей: 2014 | Зарегистр. 12-09-2002 | Отправлено: 14:32 17-05-2012
AlexPetrovich

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
SERGE_BLIZNUK
Хинты - подсказки серверу выполнить запрос наилучшим образом.
В данном случае в таблице 5 млн записей, а второе условие  
    t.grade_id between 0 and 3000000  
выбирает из них 3 млн, т.е 60% объема. Выборка с использованием индекса по t.grade_id получается неэффективной.
 
Но так как есть первое условие
t.parent_id between 5 and 5
которое выбирает только 1 запись, то индексный поиск по второму в принципе лишний.
 
Поэтому второе условие записываем в виде
t.grade_id+0 between 0 and 3000000
где (+0) - приводит к тому, что с левой стороны условия появляется выражение и по нему не будет использоваться индексный поиск. Соответственно меняется план запроса и используется только один индекс, который в данном конкретном запросе "полезен".
 
В сложных запросах хинтами мажно отключить какой-то один не нужный индекс, а использование остальных отдать на усмотрение оптимизатора (который сможет подстраивать план в зависимосити от  селективности индексов).
Если же прописывать план полностью вручную - то тут вся ответственность целиком на программере, который должен понимать, какие у него данные в БД и какие запросы будут на них работать.
 
В данном примере на 5 млн записей только у 25 из них прописан parent_id, у остальных null.  
Т.е. очень не равномерное заполнение, поэтому оптимизатор выбрал не самый скоростной план.
Но это скорее исключение, т.к. стоит немного поменять цифры в параметрах запроса и предложенный оптимизатором план станет лучшим по скорости.
 
Индексы - это не всегда полезно. Нужно думать как они будут использоваться. А то повесят на все 30 полей в таблице индексы, а потом вопросы - почему такие тормоза ?

Всего записей: 87 | Зарегистр. 08-05-2003 | Отправлено: 16:52 17-05-2012
delover

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

Цитата:
Это сильно принципиально ?  Юзер сможет заметить разницу 1 и 100 мс ?


Рад что уже появляется некоторое взаимопонимание, хотя и неполное. Теперь когда Вы гораздо лучше представляете о чём идёт речь, я повторюсь. Вернёмся к тому что я уже писал. Предположим Вы пытаетесь оптимизировать приложение разработанное не Вами и это приложение огромное (тривиальный случай). Назовём неоптимальный селект "NOS2" а оптимальный селект "OS2". Теперь смотрим на запрос:

Код:
select * from bigsel bs
join (OS2)
join (OS3)
where  
  id between 0 and 10000 and exist (OS4) and
  exist (OS5)  
 

Запрос выполняется пол минуты. Теперь замените все OS2..5 на NOS2..5. Заранее известно что NOS медленнее OS в 102 раза. По моим подсчётам вместо пол минуты будет 3 с половиной часа. Теперь вопрос - Юзер заметит разницу? Второй вопрос, когда Вы оптимизируете все подзапросы будет ли Ваш сотворённый запрос иметь отношение к стандарту SQL?  
 
 

Цитата:
Да FB  не идеален, там нет например кластерных индексов, и оптимизатор

Напоминаю - мы рассуждали о том что не устраивает в стандарте SQL. FB идеален и оптимизатор не тупит, он такой какой он есть. Хочу попробовать то же самое на MSSQL сервере. Однако:
 

Цитата:
 t.grade_id+0 between 0 and 3000000  

Это уже изменение условия, которое я называю вторичной фильтрацией. В условии будет не обязательно between и не обязательно это будет односложное условие. Там будет лес логики которую редактируете не Вы один.
 

Цитата:
Можно просто к исходному запросу приписать план  
PLAN (T INDEX (TABLE1_IDX2))  

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

Цитата:
И не нужно переписывать в 3 сджойниных подзапроса...

Скажите что в следующем запросе заставит вас подумать что это не стандарт SQL?

Код:
 
 select * from  
     table1 t  on (t.parent_id between 5 and 5)
 where
     t.grade_id between 0 and 3000000  
 

 
 
Добавлено:
И ещё очень хотел подчеркнуть разницу в кондишенах.

Код:
 
 select * from  
     table1 t  on (:cond1)  
 where  
     :cond2 or :cond3
 
-- это не тоже самое что:
 
 select * from  
     table1 t
 where  
     :cond1 and :cond2 or :cond3
 
-- однако похоже на:
 
 select * from  
     table1 t  on (:cond1)  
 where  
     :cond1 and (:cond2 or :cond3)
 

Даже скобки тут используются разумно. Реализовать первично такой стандарт -пустяковое дело. Не меняя ничего на сервере можно хотя бы эмуляцию включить пропустив текст SQL через препроцессор. А в результате в :cond1 уже можно выносить условия мастер-детейл, что увеличит читабельность...

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 21:35 17-05-2012 | Исправлено: delover, 21:37 17-05-2012
AlexPetrovich

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover
 
По моему пытаться делать оптимизацию изобретая нестандартные SQL - это путь в никуда.
Никто ради вашей задачи не будет этим заниматься.
Надо использовать те инструменты, что уже существуют.
 
Если приложение "огромное", то заказчик должен быть готов выделить на это соответствующие ресурсы, и возможно лучше в этом варианте окажется полностью переписать слой приложения который работает с БД.

Цитата:
Предположим Вы прописали все планы в хранимой процедуре а потом случайно переименовали некоторые индексы но не делали перекомпиляцию хранимых процедур. И плюс к этому обнаружили косяки только тогда когда стали переходить на новую версию сервера.

А разработчик вообще-то работу работает или "случайно" в кнопки тыкает ?
Значит не получит зарплату и в следующий раз будет внимательнее проводить тестирование.

Всего записей: 87 | Зарегистр. 08-05-2003 | Отправлено: 14:16 18-05-2012
salexn1



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

Цитата:
t.grade_id+0 between 0 and 3000000  

На MSSQL такие штуки не прокатят...
Можете не пробывать

Всего записей: 502 | Зарегистр. 21-02-2008 | Отправлено: 15:53 18-05-2012
AlexPetrovich

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
salexn1
Почему ?
 
Запрос вообще не выполнится
или индекс по t.grade_id продолжит использоваться ?
 
Не могу проверить сам.  MSSQL не установлен.

Всего записей: 87 | Зарегистр. 08-05-2003 | Отправлено: 18:01 18-05-2012
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
salexn1
Мне кажется AlexPetrovich неправильно сомневается, я тоже перепроверю. Но сейчас я в онлайн качаю танка - это тигр оборотень, жена маршал создатель.
 
Добавлю
Современные компиляторы не способны собрать программу позволяющую использовать возможности SQL.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 19:06 18-05-2012 | Исправлено: delover, 21:51 18-05-2012
salexn1



Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
AlexPetrovich
Продолжит юзать индекс. Шибко умный оптимизатор у MSSQL... В Оракле - прокатывали такие штучки (в 9 по-крайней мере)

Всего записей: 502 | Зарегистр. 21-02-2008 | Отправлено: 11:29 21-05-2012
AlexPetrovich

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

Цитата:
Современные компиляторы не способны собрать программу позволяющую использовать возможности SQL.

Жжошь!
Качай тогда лучше танка - надеюсь это у тебя получается лучше.

Всего записей: 87 | Зарегистр. 08-05-2003 | Отправлено: 10:02 22-05-2012
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
AlexPetrovich
Петровичь, я своими руками пишу в базу индексы на группу полей. Думаю Танка качать - лучше.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 18:41 22-05-2012
YuriyRR



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

Цитата:
Думаю Танка качать

О чем это вы?

Всего записей: 516 | Зарегистр. 07-06-2007 | Отправлено: 08:26 23-05-2012 | Исправлено: YuriyRR, 08:26 23-05-2012
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
YuriyRR
Оффтоп щас заработаю. Это онлайн игра, танк - персонаж который собирает максимальное количество ударов. Все бьют по нему... Так и не открыл хинты.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 22:56 23-05-2012
vetal71



Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
всем привет.
есть таблица с полем itm_order типа varchar(10). заполнена следующими значениями 1, 2, 3, 4, 11, 111, 112, 1111
необходимо после сортировки получить следующий порядок:
1
11
111
112
1111
2
3
4  
при обычной сортировке получается 1,11,1111,112
пробовал тип поля integer - получается 1,2,3,4,11...
может есть у кого какие мысли ?
 
Добавлено
должно получиться так:
1.
1.1.
1.1.1.
1.1.2.
...
1.1.11.
2.
2.1.
...
3.
...
4.
...
с точками я тоже пробовал, результата не меняет

Всего записей: 299 | Зарегистр. 08-09-2008 | Отправлено: 16:27 31-05-2012 | Исправлено: vetal71, 17:47 31-05-2012
salexn1



Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
vetal71
 
Попробуй, мот прокатит
 
select itm_order  from t1
order by SUBSTRING( itm_order  from 1 for 1)
 
З.Ы.  Не... Не прокатит
 
Добавлено:
vetal71
1111 - это 1.111 или 1.1.11 или 111.1 и т.д.
или это всегда 1.1.1.1, т.е. не может быть числа состоящего из 2-х и более цифр?
 
 
Добавлено:
Просто если мое предположение верно, можно попробовать придумать функцию, которая бы вычисляла какую-нить величину и сортировать по ней.
Ну например, т.к. у вас varchar(10) можно предположить, что макс кол-во цифр в числе 10. Придумываем функцию типа такую
 
123 = (10-1)*(10^10) - 2*(10^9) - 3*(10^8) - 0*(10^7) - 0*(10^6)...
 
 

Всего записей: 502 | Зарегистр. 21-02-2008 | Отправлено: 16:50 31-05-2012 | Исправлено: salexn1, 17:14 31-05-2012
ant0ni02004

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
vetal71
 
приводить всё к единому виду и сортировать по нему. нужно конечно знать какого вида данные
т.е.  
2.2.2.2 приводим к 02.02.02.02 - тогда оно попадёт перед 11.00.00.00
2 приводим к 02.00.00.00 итд

Всего записей: 442 | Зарегистр. 26-10-2004 | Отправлено: 18:51 31-05-2012
vetal71



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

Цитата:
salexn1
1111 - это 1.111 или 1.1.11 или 111.1 и т.д.
или это всегда 1.1.1.1, т.е. не может быть числа состоящего из 2-х и более цифр?  

 
по сути это структура меню, хранящаяся в таблице. самая большая ветка 1.1, содержит 15 пунктов, т.е. последний 1115
 

Всего записей: 299 | Зарегистр. 08-09-2008 | Отправлено: 18:53 31-05-2012
exteris

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

Цитата:
по сути это структура меню, хранящаяся в таблице. самая большая ветка 1.1, содержит 15 пунктов, т.е. последний 1115  

Как вы предлагаете определять, что 1115 - это 1.1.15, а не 1.1.1.5?

Всего записей: 382 | Зарегистр. 14-04-2003 | Отправлено: 08:20 01-06-2012
vetal71



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

Цитата:
Как вы предлагаете определять, что 1115 - это 1.1.15, а не 1.1.1.5?

да я уж понял, что надо как то переделать. должно получиться отсортированное дерево меню
Добавлено
Мне нужно как то добиться чтоб 1.1.2 находилось выше 1.1.11

Всего записей: 299 | Зарегистр. 08-09-2008 | Отправлено: 09:15 01-06-2012 | Исправлено: vetal71, 09:22 01-06-2012
salexn1



Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
vetal71
Так сохраняй с точками, что бы не было разночтений, и дополнительно добавляй 0 перед цифрами. Вряд ли в меню будет > 100 элементов, поэтому можно добавлять только 0 перед числами меньше 10.
 
Вместо 11 сохранять 01.01
Вместо 112 - 01.01.02, 1111 - 01.01.11, и т.д.

Всего записей: 502 | Зарегистр. 21-02-2008 | Отправлено: 11:40 01-06-2012
vetal71



Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
salexn1
спасибо. попробую

Всего записей: 299 | Зарегистр. 08-09-2008 | Отправлено: 20:09 01-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