Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Помогите подключить full-text search на MS SQL 7.0  [new]
Ефим
Member

Откуда:
Сообщений: 57
Есть несколько таблиц. View выбирает сводную информацию из них.
Хранимая процедура выбирает записи из view, по условию, которое определено на клиентской части. Условие, посылаемое с клиента может содержать подзапросы.
Все работает более или менее нормально, кроме одной ситуации:
Когда идет выборка по значению в двух полях, тип которых varchar (улица, дом).

Может ли в данной ситуации помочь full-text search или нужно что-то менять в хранимой процедуре?
Может быть, уходить от вложенных запросов?

И еще: Full-text indexing недоступно ни для баз, ни для таблиц. Как его доустанавливать с Windows или с SQL?
И, если можно, подробно объясните новичку как все это делается.
28 сен 04, 16:00    [993655]     Ответить | Цитировать Сообщить модератору
 Re: Помогите подключить full-text search на MS SQL 7.0  [new]
Glory
Member

Откуда:
Сообщений: 104760
Все работает более или менее нормально, кроме одной ситуации:
Когда идет выборка по значению в двух полях, тип которых varchar (улица, дом).

А нормально или ненормально это как собственно ?

Может ли в данной ситуации помочь full-text search или нужно что-то менять в хранимой процедуре?
Может быть, уходить от вложенных запросов?

Начинать нужно с простого - с анализа планов выполнения.

И еще: Full-text indexing недоступно ни для баз, ни для таблиц. Как его доустанавливать с Windows или с SQL?
И, если можно, подробно объясните новичку как все это делается.

Full-text должен быть
а) установлен с диска с SQL
б) база и таблица должна соответствовать требованиям для создания полнотекстовых индексов. Эти требования есть в BOL
28 сен 04, 17:42    [994137]     Ответить | Цитировать Сообщить модератору
 Re: Помогите подключить full-text search на MS SQL 7.0  [new]
Ефим
Member

Откуда:
Сообщений: 57
Нормально - это быстро.
В случае поиска по двум полям типа varchar - очень медленно.
Во view порядка 150 000 записей.
29 сен 04, 08:04    [994767]     Ответить | Цитировать Сообщить модератору
 Re: Помогите подключить full-text search на MS SQL 7.0  [new]
Glory
Member

Откуда:
Сообщений: 104760
Нормально - это быстро.
Быстро - понятие относительное

В случае поиска по двум полям типа varchar - очень медленно.
Получаете планы выполнения, статистику ввода/вывода и загрузки процессора "быстрого" и "медленного" запросов и сравниваете.
Можете потом воспользоваться IndexTuningWizard-ом.
29 сен 04, 10:07    [995058]     Ответить | Цитировать Сообщить модератору
 Re: Помогите подключить full-text search на MS SQL 7.0  [new]
Ефим
Member

Откуда:
Сообщений: 57
Спасибо за совет.
Теперь бы разобраться с планом выполнения.
Насколько я понял, дело все в том, что в одном случае выполняется seek по кластерным индексам (номер заказа), а в другом - кластерные индексы сканируются (поиск по улице, дому).
29 сен 04, 14:26    [996462]     Ответить | Цитировать Сообщить модератору
 Re: Помогите подключить full-text search на MS SQL 7.0  [new]
Glory
Member

Откуда:
Сообщений: 104760
Ну так если не существует никаких индексов по этим столбцам, то у сервера остается только один способ отфильтровать нужные записи - просканировать их все и сравнивать каждую на соответствие заданным условиям.
29 сен 04, 14:28    [996474]     Ответить | Цитировать Сообщить модератору
 Re: Помогите подключить full-text search на MS SQL 7.0  [new]
Ефим
Member

Откуда:
Сообщений: 57
Адреса содержатся в двух таблицах. Одна таблица основная в ней содержится еще куча другой информации, а в другой только дополнительные адреса.
И там и там есть составной индекс по улице и дому.
Но кластерный индекс - номер заказа. По нему идет связь между таблицами.
29 сен 04, 15:55    [996966]     Ответить | Цитировать Сообщить модератору
 Re: Помогите подключить full-text search на MS SQL 7.0  [new]
Glory
Member

Откуда:
Сообщений: 104760
Если хотите чтобы вам советовали что-то конкретное то
- предоставьте скрипты создания таблиц со всеми индексами
- предоставьте тексты самих запросв с планами выполнения
- сообщите приблизительное количество записей в таблицах
29 сен 04, 16:01    [996993]     Ответить | Цитировать Сообщить модератору
 Re: Помогите подключить full-text search на MS SQL 7.0  [new]
Ефим
Member

Откуда:
Сообщений: 57
CREATE TABLE [dbo].[Zakazy1] (
[nomer] [int] NULL ,
[zakaz] [varchar] (150) NULL ,
[cena] [decimal](10, 2) NULL ,
[nds] [tinyint] NULL ,
[nal_prod] [tinyint] NULL ,
[koef] [tinyint] NOT NULL ,
[pri_ur] [bit] NULL ,
[pri_teh] [bit] NULL
)
GO

CREATE TABLE [dbo].[dop_adr] (
[nomer] [int] NULL ,
[ulica1] [varchar] (40) NULL ,
[dom1] [varchar] (30) NULL ,
[liter1] [varchar] (40) NULL ,
[rayon1] [varchar] (20) NULL ,
[kvartira1] [varchar] (15) NULL ,
[pomesh1] [varchar] (15) NULL ,
[put1] [varchar] (100) NULL ,
[nn] [int] NULL
)
GO

CREATE TABLE [dbo].[Zakazy2] (
[nomer] [int] NULL ,
[nom] [smallint] NULL ,
[data_kv] [datetime] NULL ,
[kvit] [varchar] (130) NULL ,
[summa] [numeric](10, 2) NULL ,
[oplata] [bit] NULL ,
[data_opl] [datetime] NULL ,
[n_kassa] [varchar] (50) NULL ,
[tip_opl] [smallint] NULL
)
GO

CREATE TABLE [dbo].[Zakazy3] (
[nomer] [int] NULL ,
[nom] [smallint] NULL ,
[data_kv] [datetime] NULL ,
[zakaz] [varchar] (150) NULL ,
[cena] [numeric](10, 2) NULL ,
[nds] [tinyint] NULL ,
[nal_prod] [tinyint] NULL ,
[srochn] [tinyint] NULL ,
[fio] [varchar] (100) NULL ,
[ulica2] [varchar] (40) NULL ,
[dom2] [varchar] (40) NULL ,
[liter2] [varchar] (20) NULL ,
[kvartira2] [varchar] (10) NULL
)
GO

CREATE TABLE [dbo].[zklient] (
[nomer] [int] NULL ,
[nn] [int] NULL ,
[tip_kl] [smallint] NULL ,
[tip_ur] [varchar] (50) NULL ,
[fio] [varchar] (100) NULL ,
[data_rog] [smalldatetime] NULL ,
[fio_ruk] [varchar] (50) NULL ,
[dolgnost] [varchar] (50) NULL ,
[strana2] [varchar] (25) NULL ,
[gorod2] [varchar] (25) NULL ,
[ulica2] [varchar] (40) NULL ,
[dom2] [varchar] (30) NULL ,
[liter2] [varchar] (40) NULL ,
[rayon2] [varchar] (20) NULL ,
[kvartira2] [varchar] (15) NULL ,
[telefon] [varchar] (26) NULL ,
[document] [varchar] (30) NULL ,
[seriya_doc] [varchar] (15) NULL ,
[nomer_doc] [varchar] (10) NULL ,
[data_doc] [smalldatetime] NULL ,
[vydan_doc] [varchar] (50) NULL ,
[nomer_dov] [varchar] (15) NULL ,
[data_dov] [smalldatetime] NULL ,
[vydan_dov] [varchar] (50) NULL ,
[dov_na] [varchar] (50) NULL ,
[document_dov] [varchar] (30) NULL ,
[seriya_doc_dov] [varchar] (15) NULL ,
[nomer_doc_dov] [varchar] (10) NULL ,
[vydan_doc_dov] [varchar] (50) NULL ,
[data_doc_dov] [smalldatetime] NULL ,
[nomer_dov1] [varchar] (15) NULL ,
[data_dov1] [smalldatetime] NULL ,
[vydan_dov1] [varchar] (50) NULL ,
[dov_na1] [varchar] (50) NULL ,
[document_dov1] [varchar] (30) NULL ,
[seriya_doc_dov1] [varchar] (15) NULL ,
[nomer_doc_dov1] [varchar] (10) NULL ,
[vydan_doc_dov1] [varchar] (50) NULL ,
[data_doc_dov1] [smalldatetime] NULL ,
[primech] [varchar] (150) NULL ,
[po_zayav] [varchar] (50) NULL
)
GO

CREATE TABLE [dbo].[zakazy] (
[nomer] [int] NULL ,
[data] [datetime] NULL ,
[nom_dog] [int] NULL ,
[ulica1] [varchar] (40) NULL ,
[dom1] [varchar] (30) NULL ,
[liter1] [varchar] (40) NULL ,
[rayon1] [varchar] (20) NULL ,
[kvartira1] [varchar] (15) NULL ,
[pomesh1] [varchar] (15) NULL ,
[put1] [varchar] (100) NULL ,
[srochn] [tinyint] NULL ,
[srok_isp] [smalldatetime] NULL ,
[brig_vyh] [varchar] (20) NULL ,
[ispolnitel] [varchar] (20) NULL ,
[data_vyh] [smalldatetime] NULL ,
[ispolneno] [bit] NULL ,
[data_ispol] [smalldatetime] NULL ,
[provereno] [bit] NULL ,
[data_prov] [smalldatetime] NULL ,
[vydano] [bit] NULL ,
[data_vyd] [smalldatetime] NULL ,
[oper_priem] [varchar] (20) NULL ,
[oper_vyd] [varchar] (20) NULL ,
[oper_prov] [varchar] (20) NULL ,
[prichina] [varchar] (50) NULL ,
[prichina1] [varchar] (50) NULL ,
[n_schet] [tinyint] NULL ,
[kol_pasp] [int] NULL
)
GO

CREATE CLUSTERED INDEX [nom] ON [dbo].[Zakazy1]([nomer]) ON [PRIMARY]
GO

CREATE CLUSTERED INDEX [nom] ON [dbo].[dop_adr]([nomer]) ON [PRIMARY]
GO

CREATE CLUSTERED INDEX [Main] ON [dbo].[Zakazy2]([nomer]) ON [PRIMARY]
GO

CREATE CLUSTERED INDEX [Main] ON [dbo].[Zakazy3]([nomer], [nom], [data_kv]) ON [PRIMARY]
GO

CREATE CLUSTERED INDEX [Main] ON [dbo].[zklient]([nomer], [nn]) ON [PRIMARY]
GO

CREATE CLUSTERED INDEX [All] ON [dbo].[zakazy]([nomer], [data]) ON [PRIMARY]
GO

CREATE INDEX [adr] ON [dbo].[dop_adr]([ulica1], [dom1]) ON [PRIMARY]
GO

CREATE INDEX [nn] ON [dbo].[Zakazy2]([nomer]) ON [PRIMARY]
GO

CREATE INDEX [nn1] ON [dbo].[Zakazy2]([nom]) ON [PRIMARY]
GO

CREATE INDEX [kv] ON [dbo].[Zakazy2]([kvit]) ON [PRIMARY]
GO

CREATE INDEX [nomer] ON [dbo].[Zakazy3]([nomer]) ON [PRIMARY]
GO

CREATE INDEX [nomer] ON [dbo].[zklient]([nomer]) ON [PRIMARY]
GO

CREATE INDEX [nn] ON [dbo].[zklient]([nn]) ON [PRIMARY]
GO

CREATE INDEX [nn] ON [dbo].[zakazy]([nomer]) ON [PRIMARY]
GO

CREATE INDEX [da] ON [dbo].[zakazy]([data]) ON [PRIMARY]
GO

CREATE INDEX [adr] ON [dbo].[zakazy]([ulica1], [dom1]) ON [PRIMARY]
GO

SET QUOTED_IDENTIFIER OFF SET ANSI_NULLS ON
GO

CREATE VIEW dbo.vw_mon
AS
SELECT zakazy.nomer, data, nom_dog, ulica1, dom1, liter1, rayon1,
kvartira1, pomesh1, put1, srochn, srok_isp, brig_vyh, ispolnitel,
ispolneno, data_ispol, provereno, data_prov, vydano,
data_vyd, oper_priem, oper_prov, oper_vyd, tip_kl, kol_pasp,

rtrim(isnull(tip_ur, '')) + CASE WHEN tip_ur IS NOT NULL
THEN ' ' END + rtrim(isnull(fio, '')) AS fio,
prichina, oplata, data_opl, tip_opl, n_kassa, convert(float(10,2),summa) as summa,
rtrim(isnull(ulica1, '')) + CASE WHEN dom1 IS NULL
THEN '' ELSE ',д.' + rtrim(dom1)
END + CASE WHEN liter1 IS NULL
THEN '' ELSE ',л.' + rtrim(liter1)
END + CASE WHEN kvartira1 IS NULL
THEN '' ELSE ',кв.' + rtrim(kvartira1)
END + CASE WHEN pomesh1 IS NULL
THEN '' ELSE ',п.' + rtrim(pomesh1) END AS obekt
FROM zakazy, zklient, zakazy2
WHERE zakazy.nomer *= zklient.nomer AND zklient.nn = 1 AND
zakazy.nomer *= zakazy2.nomer AND kvit LIKE 'Услуги'








GO
SET QUOTED_IDENTIFIER OFF SET ANSI_NULLS ON
GO


Хороший запрос:
select * from vw_mon where nomer=138305

Плохой запрос:
select * from vw_mon where (ulica1 like '%Зорге%' and dom1='4')
or nomer in (select nomer from dop_adr where ulica1 like '%Зорге%' and dom1='4')
30 сен 04, 07:48    [998366]     Ответить | Цитировать Сообщить модератору
 Re: Помогите подключить full-text search на MS SQL 7.0  [new]
Ефим
Member

Откуда:
Сообщений: 57
Замечание: хороший запрос отрабатывает мгновенно, плохой - 18-19сек.
30 сен 04, 07:52    [998368]     Ответить | Цитировать Сообщить модератору
 Re: Помогите подключить full-text search на MS SQL 7.0  [new]
Ефим
Member

Откуда:
Сообщений: 57
Не подскажете как в сообщение на форуме вставить план выполнения?
30 сен 04, 12:40    [999468]     Ответить | Цитировать Сообщить модератору
 Re: Помогите подключить full-text search на MS SQL 7.0  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Ефим
Не подскажете как в сообщение на форуме вставить план выполнения?
Examples
This example shows how indexes are used by SQL Server as it processes the statements.

This is the query using an index:

SET SHOWPLAN_TEXT ON
GO
USE pubs
SELECT *
FROM roysched
WHERE title_id = 'PS1372'
GO
SET SHOWPLAN_TEXT OFF
GO

Here is the result set:

StmtText                                               
------------------------------------------------------ 
USE pubs

SELECT *
FROM roysched
WHERE title_id = 'PS1372'

(2 row(s) affected)

StmtText                                                                
------------------------------------------------------------------------
  |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([pubs].[dbo].[roysched]))
       |--Index Seek(OBJECT:([pubs].[dbo].[roysched].[titleidind]), SEEK:([roysched].[title_id]='PS1372') ORDERED)

(2 row(s) affected)

Here is the query not using an index:

SET SHOWPLAN_TEXT ON
GO
USE pubs
SELECT *
FROM roysched
WHERE lorange < 5000
GO
SET SHOWPLAN_TEXT OFF
GO

Here is the result set:

StmtText                                          
------------------------------------------------- 
USE pubs

SELECT *
FROM roysched
WHERE lorange < 5000

(2 row(s) affected)

StmtText                                                                
------------------------------------------------------------------------
  |--Table Scan(OBJECT:([pubs].[dbo].[roysched]), WHERE:([roysched].[lorange]<5000))

(1 row(s) affected)
30 сен 04, 13:05    [999594]     Ответить | Цитировать Сообщить модератору
 Re: Помогите подключить full-text search на MS SQL 7.0  [new]
Ефим
Member

Откуда:
Сообщений: 57
Большое чайниковское спасибо.
Вот планы плохого и хорошего запросов:

select * from vw_mon where (ulica1 like '%Зорге%' and dom1='4')
or nomer in (select nomer from dop_adr where ulica1 like '%Зорге%' and dom1='4')

(1 row(s) affected)

StmtText                                                                                                                                                                                                                                                         
  |--Compute Scalar(DEFINE:([Expr1008]=rtrim(isnull([zklient].[tip_ur], ' '))+If ([zklient].[tip_ur]<>NULL) then ' ' else NULL+rtrim(isnull([zklient].[fio], ' ')), [Expr1009]=Convert([Zakazy2].[summa]), [Expr1010]=rtrim(isnull([zakazy].[ulica1], ' '))+If (
       |--Parallelism(Gather Streams)
            |--Nested Loops(Left Outer Join)
                 |--Merge Join(Right Outer Join, MANY-TO-MANY MERGE:([Zakazy2].[nomer])=([zakazy].[nomer]), RESIDUAL:([Zakazy2].[nomer]=[zakazy].[nomer]))
                 |    |--Parallelism(Repartition Streams, PARTITION COLUMNS:([Zakazy2].[nomer]), ORDER BY:([Zakazy2].[nomer] ASC))
                 |    |    |--Filter(WHERE:(like([Zakazy2].[kvit], 'Услуги')))
                 |    |         |--Clustered Index Scan(OBJECT:([bti].[dbo].[Zakazy2].[Main]), ORDERED)
                 |    |--Filter(WHERE:((like([zakazy].[ulica1], '%Зорге%') AND [zakazy].[dom1]='4') OR [Expr1011]))
                 |         |--Merge Join(Left Semi Join, MANY-TO-MANY MERGE:([zakazy].[nomer])=([dop_adr].[nomer]), RESIDUAL:((like([dop_adr].[ulica1], '%Зорге%') AND [dop_adr].[dom1]='4') AND [zakazy].[nomer]=[dop_adr].[nomer]) OR (like([zakazy].[ulica1],
                 |              |--Parallelism(Repartition Streams, PARTITION COLUMNS:([zakazy].[nomer]), ORDER BY:([zakazy].[nomer] ASC))
                 |              |    |--Clustered Index Scan(OBJECT:([bti].[dbo].[zakazy].[All]), ORDERED)
                 |              |--Parallelism(Repartition Streams, PARTITION COLUMNS:([dop_adr].[nomer]), ORDER BY:([dop_adr].[nomer] ASC))
                 |                   |--Clustered Index Scan(OBJECT:([bti].[dbo].[dop_adr].[nom]), ORDERED)
                 |--Clustered Index Seek(OBJECT:([bti].[dbo].[zklient].[Main]), SEEK:([zklient].[nomer]=[zakazy].[nomer] AND [zklient].[nn]=1) ORDERED)

(14 row(s) affected)



StmtText                                   
------------------------------------------ 
select * from vw_mon where nomer=135200

(1 row(s) affected)

StmtText                                                                                                                                                                                                                                                        
  |--Compute Scalar(DEFINE:([Expr1006]=rtrim(isnull([zklient].[tip_ur], ' '))+If ([zklient].[tip_ur]<>NULL) then ' ' else NULL+rtrim(isnull([zklient].[fio], ' ')), [Expr1007]=Convert([Zakazy2].[summa]), [Expr1008]=rtrim(isnull([zakazy].[ulica1], ' '))+If (
       |--Nested Loops(Left Outer Join)
            |--Nested Loops(Left Outer Join)
            |    |--Clustered Index Seek(OBJECT:([bti].[dbo].[zakazy].[All]), SEEK:([zakazy].[nomer]=135200) ORDERED)
            |    |--Clustered Index Seek(OBJECT:([bti].[dbo].[zklient].[Main]), SEEK:([zklient].[nomer]=[zakazy].[nomer] AND [zklient].[nn]=1) ORDERED)
            |--Filter(WHERE:(like([Zakazy2].[kvit], 'Услуги')))
                 |--Clustered Index Seek(OBJECT:([bti].[dbo].[Zakazy2].[Main]), SEEK:([Zakazy2].[nomer]=[zakazy].[nomer]) ORDERED)
(7 row(s) affected)
30 сен 04, 13:35    [999744]     Ответить | Цитировать Сообщить модератору
 Re: Помогите подключить full-text search на MS SQL 7.0  [new]
Glory
Member

Откуда:
Сообщений: 104760
Пойдем от простого к сложному
Для начала поменяем индекс
CREATE INDEX [adr] ON [dbo].[dop_adr]([ulica1], [dom1]) ON [PRIMARY]
GO

на

CREATE INDEX [adr] ON [dbo].[dop_adr]([dom1], [ulica1]) ON [PRIMARY]
GO

Потом попробуем поменять сам запрос

select * from vw_mon where (ulica1 like '%Зорге%' and dom1='4')
union
select * from vw_mon where nomer in (select nomer from dop_adr where ulica1 like '%Зорге%' and dom1='4')
30 сен 04, 13:42    [999789]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить