powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / поиск по множеству таблиц
11 сообщений из 11, страница 1 из 1
поиск по множеству таблиц
    #32004491
zinin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
есть таблица Sites, подчинённая к ней Pages, у которой есть подчинённые Pagedata и Sectios, у которой в свою очередь есть подчинённая таблица Records.
Нужно вывести номера страниц у которых Sites.site_id=@X и поля (этих таблиц или их подчинённых) содержат задонное слово. В сумме по таблицам полей 10 штук, все они full-text index. и поиск по отдельности занимает пару милисикунд, но чтоб выполнить запрос я немогу придумать умнее чем inner join все эти 5 таблиц, а это 7 сикунд 100% загрузки.
Чё делать ? Хелп...
...
Рейтинг: 0 / 0
поиск по множеству таблиц
    #32004729
zinin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ну хоть примерно ?
...
Рейтинг: 0 / 0
поиск по множеству таблиц
    #32004737
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну Вы бы хоть примерно написали тексты Ваших запросов.

Почему мы должны в уме прикидывать чего Вы там написали, а потом прикидывать как бы это исправить?

Скорее всего Вы какое-то условие пропустили.
...
Рейтинг: 0 / 0
поиск по множеству таблиц
    #32004739
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Если всегда Sites.site_id=@X, т.е поиск идет для одной записи из таблицы Sites, то зачем ее использовать в запросе. Если можно заменить это выражение на Pages.site_id=@X (или по какому там полю связаны Sites и Pages), тогда в inner join останется только 4 таблицы - все же проще

2. Нужно натравить на запрос Index Tunning Wizard и посмотреть, что он думает об использовании существующих индексов. По своему опыту могу сказать, что наличие индекса(ов), вовсе не означает, что планировщик выполнения запроса сочтет нужным их использовать.
...
Рейтинг: 0 / 0
поиск по множеству таблиц
    #32004787
zinin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сорри, поясняю.
Нет, таблица sites не учавствует
Вот запрос

SELECT DISTINCT PAGES.page_id, PAGES.pagename
FROM SITES INNER JOIN PAGES
ON SITES.site_id = PAGES.site_id LEFT JOIN SECTIONS
ON PAGES.page_id = SECTIONS.page_id LEFT JOIN RECORDS
ON SECTIONS.section_id = RECORDS.section_id INNER JOIN PAGEDATA
ON PAGES.page_id = PAGEDATA.page_id
WHERE (PAGES.type != 16) AND (SITES.site_id = 4) AND (PAGES.hidden != 1) AND (
pages.pagename like '%str%' or
contains(sections.text1, 'str') or
contains(section_name, 'str') or
contains(pagedata.data_value, 'str') or
contains(records.str50, 'str') or
contains(records.str100, 'str') or
contains(records.string1, 'str') or
contains(records.string2, 'str') or
contains(records.string3, 'str') or
contains(records.text1, 'str') or
contains(records.text2, 'str')
)

А вот "план"...


|--Hash Match(Aggregate, HASH[PAGES].[page_id]) DEFINE[PAGES].[pagename]=ANY([PAGES].[pagename])))
|--Filter(WHERE(((((((((like([PAGES].[pagename], '%str%') OR [Expr1030]) OR [Expr1031]) OR [Expr1032]) OR [Expr1033]) OR [Expr1034]) OR [Expr1035]) OR [Expr1036]) OR [Expr1037]) OR [Expr1038]) OR [Expr1039]))
|--Merge Join(Left Semi Join, MANY-TO-MANY MERGE[SECTIONS].[section_id])=([].[KEY]), RESIDUAL[SECTIONS].[section_id]=[].[KEY]) OR (((((((((like([PAGES].[pagename], '%str%') OR [Expr1030]) OR [Expr1031]) OR [Expr1032]) OR [Expr1033]) OR [Exp
|--Merge Join(Left Semi Join, MANY-TO-MANY MERGE[SECTIONS].[section_id])=([].[KEY]), RESIDUAL[SECTIONS].[section_id]=[].[KEY]) OR ((((((((like([PAGES].[pagename], '%str%') OR [Expr1030]) OR [Expr1031]) OR [Expr1032]) OR [Expr1033]) OR
| |--Sort(ORDER BY[SECTIONS].[section_id] ASC))
| | |--Merge Join(Left Semi Join, MANY-TO-MANY MERGE[PAGEDATA].[data_value])=([].[KEY]), RESIDUAL[PAGEDATA].[data_value]=[].[KEY]) OR (((((((like([PAGES].[pagename], '%str%') OR [Expr1030]) OR [Expr1031]) OR [Expr1032]) OR [Expr1
| | |--Sort(ORDER BY[PAGEDATA].[data_value] ASC))
| | | |--Nested Loops(Left Semi Join, WHERE(((((like([PAGES].[pagename], '%str%') OR [Expr1030]) OR [Expr1031]) OR [Expr1032]) OR [Expr1033]) OR [Expr1034]) OR [Expr1035]))
| | | |--Nested Loops(Left Semi Join, WHERE((((like([PAGES].[pagename], '%str%') OR [Expr1030]) OR [Expr1031]) OR [Expr1032]) OR [Expr1033]) OR [Expr1034]))
| | | | |--Nested Loops(Left Semi Join, WHERE(((like([PAGES].[pagename], '%str%') OR [Expr1030]) OR [Expr1031]) OR [Expr1032]) OR [Expr1033]))
| | | | | |--Nested Loops(Left Semi Join, WHERE((like([PAGES].[pagename], '%str%') OR [Expr1030]) OR [Expr1031]) OR [Expr1032]))
| | | | | | |--Nested Loops(Left Semi Join, WHERE(like([PAGES].[pagename], '%str%') OR [Expr1030]) OR [Expr1031]))
| | | | | | | |--Nested Loops(Left Semi Join, WHERElike([PAGES].[pagename], '%str%') OR [Expr1030]))
| | | | | | | | |--Nested Loops(Left Semi Join, WHERElike([PAGES].[pagename], '%str%')))
| | | | | | | | | |--Merge Join(Right Outer Join, MANY-TO-MANY MERGE[RECORDS].[section_id])=([SECTIONS].[section_id]), RESIDUAL[SECTIONS].[section_id]=[RECORDS].[section_id]))
| | | | | | | | | | |--Index Scan(OBJECT[aim].[dbo].[RECORDS].[IX_RECORDS_SE]), ORDERED)
| | | | | | | | | | |--Sort(ORDER BY[SECTIONS].[section_id] ASC))
| | | | | | | | | | |--Nested Loops(Left Outer Join)
| | | | | | | | | | |--Nested Loops(Inner Join)
| | | | | | | | | | | |--Clustered Index Seek(OBJECT[aim].[dbo].[SITES].[PK_SITES]), SEEK[SITES].[site_id]=4) ORDERED)
| | | | | | | | | | | |--Hash Match(Inner Join, HASH[PAGES].[page_id])=([PAGEDATA].[page_id]))
| | | | | | | | | | | |--Filter(WHERE[PAGES].[type]<>16 AND [PAGES].[hidden]<>1))
| | | | | | | | | | | | |--Clustered Index Scan(OBJECT[aim].[dbo].[PAGES].[PK_PAGES]), WHERE[PAGES].[site_id]=4))
| | | | | | | | | | | |--Clustered Index Scan(OBJECT[aim].[dbo].[PAGEDATA].[PK_PAGEDATA]))
| | | | | | | | | | |--Index Seek(OBJECT[aim].[dbo].[SECTIONS].[IX_SECTIONS_P]), SEEK[SECTIONS].[page_id]=[PAGES].[page_id]) ORDERED)
| | | | | | | | | |--Row Count Spool
| | | | | | | | | |--Index Spool(SEEK[].[KEY]=[RECORDS].[text2]))
| | | | | | | | | |--Remote Scan(CONTAINS)
| | | | | | | | |--Row Count Spool
| | | | | | | | |--Index Spool(SEEK[].[KEY]=[RECORDS].[text2]))
| | | | | | | | |--Remote Scan(CONTAINS)
| | | | | | | |--Row Count Spool
| | | | | | | |--Index Spool(SEEK[].[KEY]=[RECORDS].[text2]))
| | | | | | | |--Remote Scan(CONTAINS)
| | | | | | |--Row Count Spool
| | | | | | |--Index Spool(SEEK[].[KEY]=[RECORDS].[text2]))
| | | | | | |--Remote Scan(CONTAINS)
| | | | | |--Row Count Spool
| | | | | |--Index Spool(SEEK[].[KEY]=[RECORDS].[text2]))
| | | | | |--Remote Scan(CONTAINS)
| | | | |--Row Count Spool
| | | | |--Index Spool(SEEK[].[KEY]=[RECORDS].[text2]))
| | | | |--Remote Scan(CONTAINS)
| | | |--Row Count Spool
| | | |--Index Spool(SEEK[].[KEY]=[RECORDS].[text2]))
| | | |--Remote Scan(CONTAINS)
| | |--Sort(ORDER BY[].[KEY] ASC))
| | |--Remote Scan(CONTAINS)
| |--Sort(ORDER BY[].[KEY] ASC))
| |--Remote Scan(CONTAINS)
|--Sort(ORDER BY[].[KEY] ASC))
|--Remote Scan(CONTAINS)
...
Рейтинг: 0 / 0
поиск по множеству таблиц
    #32004788
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А если заменить все LEFT JOIN на INNER JOIN ?

Сколько выдаст такой запрос?
SELECT count(*)
FROM SITES INNER JOIN PAGES
ON SITES.site_id = PAGES.site_id LEFT JOIN SECTIONS
ON PAGES.page_id = SECTIONS.page_id LEFT JOIN RECORDS
ON SECTIONS.section_id = RECORDS.section_id INNER JOIN PAGEDATA
ON PAGES.page_id = PAGEDATA.page_id
WHERE (PAGES.type != 16) AND (SITES.site_id = 4) AND (PAGES.hidden != 1)

Ну и думайте исходя из получившийся результатов. Если всё равно будет долго, посмотрите опцию SET FORCEPLAN { ON | OFF }, может наведет на какие мысли. Мне кажется на первый взгяд что Вы не вполне осознанно пишите LEFT JOIN и получается очень большую выборку.
...
Рейтинг: 0 / 0
поиск по множеству таблиц
    #32004867
zinin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Запрос выдал 96252

A Left Join - потому что не всегда есть записи у страниц, но страницу нужно найти. То же и про разделы.
...
Рейтинг: 0 / 0
поиск по множеству таблиц
    #32004870
Genady
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Думаю, что дело не в том, что у Вас соединяется 5 таблиц, а в том, что слишком много условий OR, серверу не только нужно вернуть много записей а еще и найти их по такому условию 8(
Полагаю Вам нужно пересмотреть способ получения данных, например выполнить несколько запросов, в которых не будет OR.
...
Рейтинг: 0 / 0
поиск по множеству таблиц
    #32004873
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 zinin
Ну а что тогда удивляться? У Вас сервер должен просканировать 100 000 записей(и это не считая тех, которые не прошли по условию (PAGES.type != 16) AND (SITES.site_id = 4) AND (PAGES.hidden != 1))

Чтобы быстрей сделать, тут уже самому придется думать за сервер. Как я понял у вас есть некие условия и хотя бы одно должно удовлетворяться. Делайте временную таблицу и добавляйте туда нужные записи по частям. Тогда можно будет уйти от LEFT JOIN-ов. И заодно разнесёте ORы, так чтобы в одном выражении не было OR двух полей разных таблиц. В идеале конечно лучше вообще без OR, но у Вас уж больно много получиться тогда заросов.

С приветом Сергей
PS. Извиняюсь, ну не смог таки удержаться

Нужно вывести номера страниц у которых Sites.site_id=@X и поля (этих таблиц или их подчинённых) содержат зад о нное слово. В сумме по таблицам полей 10 штук, все они full-text index. и поиск по отдельности занимает пару милис и кунд, но чтоб выполнить запрос я немогу придумать умнее чем inner join все эти 5 таблиц, а это 7 с и кунд 100% загрузки.
...
Рейтинг: 0 / 0
поиск по множеству таблиц
    #32005008
zinin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я молдаванин, мне простительно.

Я вообще-то ожидал не такого ответа.

Скорее всего, такие поиски проводятся совсем не так, но вот как?
Я не думаю что столкнулся с этой проблемой первый, и наверно давно есть ответ.
Но вот какой и где его искать?
...
Рейтинг: 0 / 0
поиск по множеству таблиц
    #32005268
Могу подкинуть идейку (не знаю, может быть, так писать - дурной тон, но работает быстрее):

Вместо

select t1.field1 from t1
inner join t2 on t1.key1=t2.key1
inner join t3 on t2.key2=t3.key2
where t1.???=??? or t2.???=??? or t3.???=???

можно использовать что-то типа

select t1.field1 from t1 where t1.???=??? or
t1.key1 in (select t2.key1 from t2 where t2.???=??? or
t2.key2 in (select t3.key2 from t3 where t3.???=???)

Уже на тройном join'е дает повышение быстродействия.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / поиск по множеству таблиц
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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