powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите с индексами
25 сообщений из 34, страница 1 из 2
Помогите с индексами
    #39369304
__Avenger__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день!

Помогите привести такой запрос к максимальной скорости получения всех записей:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
CREATE TABLE SEA (
    WORD_ID    INTEGER NOT NULL,
    OBJECT_ID  CHAR(16) CHARACTER SET OCTETS NOT NULL,
    NS_LEFT    INTEGER NOT NULL,
    NS_RIGHT   INTEGER NOT NULL
);

SELECT t1.object_id as obj_id
FROM sea t1
inner join sea t2
   on t2.ns_left  < t1.ns_right
  and t2.ns_right > t1.ns_left
group by t1.object_id, t1.ns_left, t1.ns_right
having count(distinct t2.word_id) >= 3
   and t1.ns_left  = max(t2.ns_left)
   and t1.ns_right = min(t2.ns_right)



Какие индексы лучше всего добавить?
...
Рейтинг: 0 / 0
Помогите с индексами
    #39369305
__Avenger__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Количество записей в таблице до 1 млн.
FB 2.5.6
...
Рейтинг: 0 / 0
Помогите с индексами
    #39369808
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__Avenger__, нужен план запроса.
...
Рейтинг: 0 / 0
Помогите с индексами
    #39369817
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev,

я тебе и без плана скажу что эффективность такого JOIN будет так себе, а вот как можно улучшить пока не вижу
...
Рейтинг: 0 / 0
Помогите с индексами
    #39369866
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__Avenger__, объясни словами, что ты хочешь получить представленным запросом.
...
Рейтинг: 0 / 0
Помогите с индексами
    #39369946
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__Avenger__, это:
Код: plsql
1.
2.
   and t1.ns_left  = max(t2.ns_left)
   and t1.ns_right = min(t2.ns_right)

полнейшая галиматья.
Такое утверждение возможно только при условии что t1.object_id = t2.object_id и этот узел не имеет дочерних элементов, а следовательно:
Код: plsql
1.
count(distinct t2.word_id) >= 3 

не имеет смысла и весь запрос никаких данных не возвращает.

Получение всех конечных узлов дерева:
Код: plsql
1.
2.
3.
SELECT object_id
  FROM sea
  WHERE ns_right - ns_left = 1


Получение кол-ва всех дочерних узлов каждого узла дерева:
Код: plsql
1.
2.
SELECT object_id, (ns_right - ns_left - 1) / 2 AS child_count
  FROM sea


Получение всех дочерних узлов каждого узла:
Код: plsql
1.
2.
3.
4.
SELECT node.object_id AS node_id, child.object_id AS id
  FROM sea node
    INNER JOIN sea child
      ON child.ns_left > node.ns_left AND child.ns_right < node.ns_right
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370044
__Avenger__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кто говорит голимотья, смотрите тестовые данные.
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370054
__Avenger__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev__Avenger__, это:
Код: plsql
1.
2.
   and t1.ns_left  = max(t2.ns_left)
   and t1.ns_right = min(t2.ns_right)

полнейшая галиматья.
Такое утверждение возможно только при условии что t1.object_id = t2.object_id и этот узел не имеет дочерних элементов, а

Не говорите ерундой. Это не полнейшая галиматья, это дополнительные фильтры.
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370061
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__Avenger__, и что там надо развидеть? Кривую ключевую информацию, при которой
Код: plsql
1.
2.
3.
count(distinct t2.word_id) >= 3
   and t1.ns_left  = max(t2.ns_left)
   and t1.ns_right = min(t2.ns_right)

имеет смысл?

Попробуй сам применить данное условие к любому узлу из примера:
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370064
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__Avenger__,

что же ты DDL даёшь которая не соответствует скрипту загрузки
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370073
__Avenger__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис__Avenger__,

что же ты DDL даёшь которая не соответствует скрипту загрузки

Я исправлюсь. Сейчас расскажу о самой задаче с тестовыми данными.
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370080
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__Avenger__,

да поправил под твой скрипт уже


Код: sql
1.
2.
3.
4.
5.
6.
CREATE TABLE SEA (
    ROW_ID     INTEGER NOT NULL,
    OBJECT_ID  CHAR(36) NOT NULL,
    NS_LEFT    INTEGER NOT NULL,
    NS_RIGHT   INTEGER NOT NULL
);



а вот что за задачу решаешь хотелось бы услышать
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370094
__Avenger__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задача – поиск адресных объектов в системе ФИАС
Пусть у нас есть поисковый запрос «санкт новгор стар». Пронумируем слова:
WordID = 1 - санкт
WordID = 2 - новгор
WordID = 3 - стар
Система вернет в таблицу
Код: sql
1.
2.
3.
4.
5.
6.
CREATE TABLE FIAS$SEARCH_PREPARE (
    WORD_ID    D$INTEGER NOT NULL,
    OBJECT_FK  D$GUID NOT NULL,
    NS_LEFT    D$INTEGER DEFAULT 0 NOT NULL,
    NS_RIGHT   D$INTEGER DEFAULT 0 NOT NULL
);


данные, которые представлены во вложенном файле. Как видно в поисковом запросе используется три слова.

Данному запросу будет соответствовать один верный ответ -

743FA475-8AFA-4CAF-B211-0F0372A2D762:


Код: plaintext
1.
2.
3.
4.
OBJECT_ID	PARENT_FK	NAME	NS_LEFT	NS_RIGHT
743FA475-8AFA-4CAF-B211-0F0372A2D762    BC4E8FBC-54DC-4114-9C48-FD7A9B3E2E5C    Санкт-Петербургская 1411152 1411153
BC4E8FBC-54DC-4114-9C48-FD7A9B3E2E5C    AB9218FD-CB07-4BB8-AFF2-EE3D735E9CAC    Старая Русса        1410849 1411248
AB9218FD-CB07-4BB8-AFF2-EE3D735E9CAC    E5A84B81-8EA1-49E3-B3C4-0528651BE129    Старорусский        1409768 1411261
E5A84B81-8EA1-49E3-B3C4-0528651BE129    NULL                                    Новгородская        1393227 1414996

потому что, его интервал лежит внутри двух других интервалов, в которых встречаются оставшиеся поисковые слова

1393227 < 1409768 < 1410849 < 1411152 1411153 < 1411248 < 1411261 < 1414996
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370105
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__Avenger__,

я до конца не врубился, но для твоего изначального запроса подойдут обычные индексы.

Код: sql
1.
2.
CREATE INDEX IDX_SEA_LEFT ON SEA(NS_LEFT);
CREATE INDEX IDX_SEA_RIGHT ON SEA(NS_RIGHT);



Композиты ничего не улучшат. Игры с ASC DESC тоже, ибо всё равно уйдёт на внешнюю сортировку.
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370115
__Avenger__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис__Avenger__,

я до конца не врубился, но для твоего изначального запроса подойдут обычные индексы.
Композиты ничего не улучшат. Игры с ASC DESC тоже, ибо всё равно уйдёт на внешнюю сортировку.

Спасибо, я модифицировал запрос на такой:
Код: sql
1.
2.
3.
4.
5.
6.
7.
      SELECT T1.OBJECT_FK
      FROM FIAS$SEARCH_PREPARE T1
      INNER JOIN FIAS$SEARCH_PREPARE T2
         ON T1.NS_LEFT  BETWEEN T2.NS_LEFT AND T2.NS_RIGHT
        AND T1.NS_RIGHT BETWEEN T2.NS_LEFT AND T2.NS_RIGHT
      GROUP BY T1.NS_LEFT, T1.NS_RIGHT, T1.OBJECT_FK
      HAVING COUNT(DISTINCT T2.WORD_ID) >= (SELECT COUNT(DISTINCT WORD_ID) FROM FIAS$SEARCH_PREPARE)



Добавлено два индекса:
Код: sql
1.
2.
ALTER TABLE FIAS$SEARCH_PREPARE ADD CONSTRAINT FIAS$SEARCH_PREPARE$PK PRIMARY KEY (WORD_ID, OBJECT_FK);
CREATE INDEX FIAS$SEARCH_PREPARE$IDX_NS_PAIR ON FIAS$SEARCH_PREPARE (NS_LEFT, NS_RIGHT, OBJECT_FK);
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370127
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__Avenger__, так чтоль?
Код: plsql
1.
2.
3.
4.
5.
6.
SELECT node.object_id AS node_id
  FROM sea node
    INNER JOIN sea child
      ON child.ns_left > node.ns_left AND child.ns_right < node.ns_right
  GROUP BY node.object_id
  HAVING Count(DISTINCT t2.word_id) > 2

или
Код: plsql
1.
2.
3.
4.
5.
6.
SELECT node.object_id AS node_id
  FROM sea node
    INNER JOIN sea child
      ON child.ns_left > node.ns_left AND child.ns_right < node.ns_right
    INNER JOIN words ON words.id = child.word_id
  WHERE words.plain IN ('санкт', 'новгор', 'стар')


Что должно быть в результирующем наборе строк?
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370129
Фотография Di_LIne
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__Avenger__Задача – поиск адресных объектов в системе ФИАС
Пусть у нас есть поисковый запрос «санкт новгор стар». Пронумируем слова:

Хм...
Ну и как ты собираешься отделять Новгород (Великий) и Нижний Новгород?
И Санкт-Петербург от Санкт-Петербургоского шоссе и банка Санкт-Петербург?
Такшта - КГ, автор - двоешнег по Русскому языку.
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370135
__Avenger__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Di_LIne__Avenger__Задача – поиск адресных объектов в системе ФИАС
Пусть у нас есть поисковый запрос «санкт новгор стар». Пронумируем слова:

Хм...
Ну и как ты собираешься отделять Новгород (Великий) и Нижний Новгород?
И Санкт-Петербург от Санкт-Петербургоского шоссе и банка Санкт-Петербург?
Такшта - КГ, автор - двоешнег по Русскому языку.

Запрос отделяет, если на одной ветке лежат все поисковые слова. Приведи пример, прогоню на данных.
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370139
__Avenger__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev__Avenger__, так чтоль?
Код: plsql
1.
2.
3.
4.
5.
6.
SELECT node.object_id AS node_id
  FROM sea node
    INNER JOIN sea child
      ON child.ns_left > node.ns_left AND child.ns_right < node.ns_right
  GROUP BY node.object_id
  HAVING Count(DISTINCT t2.word_id) > 2



Результат:
NODE_ID ADDRESS
AB9218FD-CB07-4BB8-AFF2-EE3D735E9CAC , Новгородская обл, , Старорусский р-н, , , ,
C2DEB16A-0330-4F05-821F-1D09C93331E6 190000, Санкт-Петербург г, , , , , ,
E5A84B81-8EA1-49E3-B3C4-0528651BE129 , Новгородская обл, , , , , ,
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370142
__Avenger__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devЧто должно быть в результирующем наборе строк?


Данному запросу будет соответствовать один верный ответ -

743FA475-8AFA-4CAF-B211-0F0372A2D762:
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370145
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__Avenger__, как так? В запросе же была ошибка... Надо после DISTINCT "t2" заменить на "child"
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370149
__Avenger__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev__Avenger__, как так? В запросе же была ошибка... Надо после DISTINCT "t2" заменить на "child"

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select t.node_id, gfu.address from (
SELECT node.object_fk AS node_id
  FROM FIAS$SEARCH_PREPARE node
    INNER JOIN FIAS$SEARCH_PREPARE child
      ON child.ns_left > node.ns_left AND child.ns_right < node.ns_right
  GROUP BY node.object_fk
  HAVING Count(DISTINCT child.word_id) > 2
) t
    LEFT OUTER JOIN FIAS$GET_FULL_ADDRESS(t.node_id, '', '', 0) GFU ON 0 = 0t
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370175
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__Avenger__, запрос с
Код: plsql
1.
HAVING Count(DISTINCT child.word_id) > 2

возвращает корни ветвей, содержащие в дочерних узлах более двух уникальных ключевых слов. Firebird мысли читать не умеет и ключевые слова не угадывает. Этот запрос - пересмотр твоего запроса в топике. Смотри мой второй запрос:
Код: plsql
1.
2.
3.
4.
5.
6.
SELECT node.object_id AS node_id
  FROM sea node
    INNER JOIN sea child
      ON child.ns_left > node.ns_left AND child.ns_right < node.ns_right
    INNER JOIN words ON words.id = child.word_id
  WHERE words.plain IN ('санкт', 'новгор', 'стар')
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370184
Фотография Di_LIne
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
__Avenger__Запрос отделяет, если на одной ветке лежат все поисковые слова.
- Не ври, да?...


__Avenger__Задача – поиск адресных объектов в системе ФИАС
Пусть у нас есть поисковый запрос «санкт новгор стар».

Данному запросу будет соответствовать один верный ответ -

743FA475-8AFA-4CAF-B211-0F0372A2D762:


OBJECT_ID PARENT_FK NAME NS_LEFT NS_RIGHT
743FA475-8AFA-4CAF-B211-0F0372A2D762 BC4E8FBC-54DC-4114-9C48-FD7A9B3E2E5C Санкт-Петербургская 1411152 1411153

Где в представленном тобой "результате" есть соответствие на "новгор стар"?

ТО, что в основе глупая идея "отбросить окончания" - для меня очам_видна и так.

Пример я тебе привел. Если не видишь, то пишу еше раз:
Города Новгород и Нижний Новгород - два разных субъекта РФ.
- Так понятно?
...
Рейтинг: 0 / 0
Помогите с индексами
    #39370209
__Avenger__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Di_LIneПример я тебе привел. Если не видишь, то пишу еше раз:
Города Новгород и Нижний Новгород - два разных субъекта РФ.
- Так понятно?

А в чем проблема, они в дереве будут лежать на разных уровнях и принадлежать разным интервалам. Не вижу проблемы.
...
Рейтинг: 0 / 0
25 сообщений из 34, страница 1 из 2
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите с индексами
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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