I have 2 identical database, replicated. the table structure, indexes, text indexes, and data are identical. both servers are running the same exact version of sql server
Microsoft SQL Server 2008 (SP3) - 10.0.5512.0 (X64) Aug 22 2012 19:25:47 Copyright (c) 1988-2008 Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
on one server the query (a complicated search on a dozen optional fields in various tables including several text strings - the text search improvements of sql2012 will allow me to simplify the text searching, but that is in the future)
the query finishes in a few seconds, on the other server it is taking minutes.
I have narrowed the problem to a left join to a table with 83,000 rows which looks things up via the primary clustered index
I cannot see why this should has any serious effect on performance. I have rebuilt the test indexes and done a dbreindex on the offending table
am am including the creation script for the FK table followed by the query. the query is from the SP, with the parameters changed to a declare and set to provide the passed parameters, the commented out sections have no performance effect. it is the last left join causing the problem.
USE [recordings]GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[broadcast_barcodes](
[broadcast_archive_num] [int] NOT NULL,
[barcode] [char](10) NOT NULL,
[rowguid] [uniqueidentifier] ROWGUIDCOL NOT NULL,
CONSTRAINT [PK_broadcast_barcodes] PRIMARY KEY CLUSTERED
(
[broadcast_archive_num] ASC,
[barcode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
USE [recordings]
CREATE UNIQUE NONCLUSTERED INDEX [Index_broadcast_barcodes_rg] ON [dbo].[broadcast_barcodes]
(
[rowguid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [index]
GO
USE [recordings]
CREATE UNIQUE NONCLUSTERED INDEX [IX_broadcast_barcodes] ON [dbo].[broadcast_barcodes]
(
[barcode] ASC,
[broadcast_archive_num] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [index]
GO
ALTER TABLE [dbo].[broadcast_barcodes] WITH NOCHECK ADD CONSTRAINT [FK_broadcast_barcodes_barcodes] FOREIGN KEY([barcode])
REFERENCES [dbo].[barcodes] ([barcode])
NOT FOR REPLICATION
GO
ALTER TABLE [dbo].[broadcast_barcodes] CHECK CONSTRAINT [FK_broadcast_barcodes_barcodes]
GO
ALTER TABLE [dbo].[broadcast_barcodes] WITH CHECK ADD CONSTRAINT [FK_broadcast_barcodes_broadcast_barcodes] FOREIGN KEY([broadcast_archive_num])
REFERENCES [dbo].[broadcasts] ([broadcast_archive_num])
GO
ALTER TABLE [dbo].[broadcast_barcodes] CHECK CONSTRAINT [FK_broadcast_barcodes_broadcast_barcodes]
GO
ALTER TABLE [dbo].[broadcast_barcodes] ADD CONSTRAINT [DF_broadcast_barcodes_rowguid] DEFAULT (newsequentialid()) FOR [rowguid]
GO
=============================================================================
declare @subnet varchar(20),@text nvarchar(50),@search_type tinyint,@channel tinyint,@from_date date,@to_date date,@broadcast_items xml
,@job tinyint,@workers xml,@has_digital_media bit
,@inc_spokesman bit,@inc_nonspokesman bit,@people xml,@topic xml
BEGIN
set @subnet=N'192.168.4.0'
set @text=N'משפט ג''ון' set @search_type=1 set @inc_spokesman=1 set @inc_nonspokesman=1
/*
exec dbo.item_adv_search
@subnet='192.168.4.0',
@text='כותרת',
@search_type=1,
@channel = null,
@from_date = '2013-02-01',
@to_date = '2013-02-28',
@broadcast_items=null,--'<root><r item="3"/></root>', -- or null
@job = null,
@workers = null,--'<root><r worker="3"/></root>', -- or null
@has_digital_media=null,
@inc_spokesman='1',
@inc_nonspokesman='1',
@people = null,--'<root><r person="3"/></root>', -- or null
@topic = null--'<root><r topic="3"/></root>' -- or null
*/
declare @idoc int
declare @bitems table(item int)
declare @emps table (emp int)
declare @guests table(guest int)
declare @topics table(subjects tinyint)
declare @res table
(broadcast_archive_num int,item_archive_num int,sort_order int,
broadcast_date date,broadcast_time time(0),
channel_code tinyint,channel_desc nvarchar(20),
broadcast_item_name nvarchar(70),item_title nvarchar(200),item_desc nvarchar(max),
Spokesman_str nvarchar(100), Reference_str nvarchar(100),
digital_media_url varchar(100),file_code int,
barcode char(10),lush_broadcast_item_code int,file_cnt smallint,play_cnt smallint)
-- load chosen broadcast_items
--if @broadcast_items is not null
-- begin
-- EXEC sp_xml_preparedocument @idoc OUTPUT, @broadcast_items
-- INSERT INTO @bitems(item)
--SELECT item
--FROM OPENXML (@idoc, '/root/r',1)
--WITH (item int)
-- exec sp_xml_removedocument @idoc
-- end
-- -- load chosen workers
--if @workers is not null
-- begin
-- EXEC sp_xml_preparedocument @idoc OUTPUT, @workers
-- INSERT INTO @emps(emp)
--SELECT worker
--FROM OPENXML (@idoc, '/root/r',1)
--WITH (worker int)
-- exec sp_xml_removedocument @idoc
-- end
-- -- load chosen people
--if @people is not null
-- begin
-- EXEC sp_xml_preparedocument @idoc OUTPUT, @people
-- INSERT INTO @guests(guest)
--SELECT person
--FROM OPENXML (@idoc, '/root/r',1)
--WITH (person int)
-- exec sp_xml_removedocument @idoc
-- end
-- -- load chosen topics
--if @topic is not null
-- begin
-- EXEC sp_xml_preparedocument @idoc OUTPUT, @topic
-- INSERT INTO @topics(subjects)
--SELECT topic
--FROM OPENXML (@idoc, '/root/r',1)
--WITH (topic int)
-- exec sp_xml_removedocument @idoc
-- end
declare @junk nvarchar(20)='rwcwcqw978fsadf7qwer'
declare @word1 nvarchar(25)=@junk
declare @word2 nvarchar(25)=@junk
declare @word3 nvarchar(25)=@junk
declare @word4 nvarchar(25)=@junk
declare @word5 nvarchar(25)=@junk
declare @word1a nvarchar(25)=@junk
declare @word2a nvarchar(25)=@junk
declare @word3a nvarchar(25)=@junk
declare @word4a nvarchar(25)=@junk
declare @word5a nvarchar(25)=@junk
declare @word1b nvarchar(25)=@junk
declare @word2b nvarchar(25)=@junk
declare @word3b nvarchar(25)=@junk
declare @word4b nvarchar(25)=@junk
declare @word5b nvarchar(25)=@junk
declare @word1c nvarchar(25)=@junk
declare @word2c nvarchar(25)=@junk
declare @word3c nvarchar(25)=@junk
declare @word4c nvarchar(25)=@junk
declare @word5c nvarchar(25)=@junk
declare @word1d nvarchar(25)=@junk
declare @word2d nvarchar(25)=@junk
declare @word3d nvarchar(25)=@junk
declare @word4d nvarchar(25)=@junk
declare @word5d nvarchar(25)=@junk
declare @word1e nvarchar(25)=@junk
declare @word2e nvarchar(25)=@junk
declare @word3e nvarchar(25)=@junk
declare @word4e nvarchar(25)=@junk
declare @word5e nvarchar(25)=@junk
declare @word1f nvarchar(25)=@junk
declare @word2f nvarchar(25)=@junk
declare @word3f nvarchar(25)=@junk
declare @word4f nvarchar(25)=@junk
declare @word5f nvarchar(25)=@junk
declare @loc tinyint,@copy_text nvarchar(70)=dbo.trim(@text)
-- type 2 (use phrase as string)
declare @ftext nvarchar(60) ='"'+@text+'"'
-- type 1 (break into separate words)
set @copy_text=replace(@copy_text,'"','""')
set @copy_text=replace(@copy_text,'''','''''')
if isnull(@copy_text,'')='' goto done_word_break
set @loc =charindex(' ',@copy_text)
if @loc=0
begin
set @word1=@copy_text
set @word1a='"'+@copy_text+'*"'
goto done_word_break
end
else begin
set @word1=left(@copy_text,@loc-1)
set @word1a='"'+left(@copy_text,@loc-1)+'*"'
set @copy_text=ltrim(substring(@copy_text,@loc+1,100))
end
set @loc =charindex(' ',@copy_text)
if @loc=0
begin
set @word2=@copy_text
set @word2a='"'+@copy_text+'*"'
goto done_word_break
end
else begin
set @word2=left(@copy_text,@loc-1)
set @word2a='"'+left(@copy_text,@loc-1)+'*"'
set @copy_text=ltrim(substring(@copy_text,@loc+1,100))
end
set @loc =charindex(' ',@copy_text)
if @loc=0
begin
set @word3=@copy_text
set @word3a='"'+@copy_text+'*"'
goto done_word_break
end
else begin
set @word3=left(@copy_text,@loc-1)
set @word3a='"'+left(@copy_text,@loc-1)+'*"'
set @copy_text=ltrim(substring(@copy_text,@loc+1,100))
end
set @loc =charindex(' ',@copy_text)
if @loc=0
begin
set @word4=@copy_text
set @word4a='"'+@copy_text+'*"'
goto done_word_break
end
else begin
set @word4=left(@copy_text,@loc-1)
set @word4a='"'+left(@copy_text,@loc-1)+'*"'
set @copy_text=ltrim(substring(@copy_text,@loc+1,100))
end
set @loc =charindex(' ',@copy_text)
if @loc=0
begin
set @word5=@copy_text
set @word5a='"'+@copy_text+'*"'
goto done_word_break
end
else begin
set @word5=left(@copy_text,@loc-1)
set @word5a='"'+left(@copy_text,@loc-1)+'*"'
set @copy_text=ltrim(substring(@copy_text,@loc+1,100))
end
done_word_break:
set @word1b='ב'+@word1
set @word1c='ה'+@word1
set @word1d='ו'+@word1
set @word1e='ל'+@word1
set @word1f='מ'+@word1
set @word2b='ב'+@word2
set @word2c='ה'+@word2
set @word2d='ו'+@word2
set @word2e='ל'+@word2
set @word2f='מ'+@word2
set @word3b='ב'+@word3
set @word3c='ה'+@word3
set @word3d='ו'+@word3
set @word3e='ל'+@word3
set @word3f='מ'+@word3
set @word4b='ב'+@word4
set @word4c='ה'+@word4
set @word4d='ו'+@word4
set @word4e='ל'+@word4
set @word4f='מ'+@word4
set @word5b='ב'+@word5
set @word5c='ה'+@word5
set @word5d='ו'+@word5
set @word5e='ל'+@word5
set @word5f='מ'+@word5
set @from_date=isnull(@from_date,'1900-1-1')
set @to_date=isnull(@to_date,'2078-12-31')
--insert into @res
-- (broadcast_archive_num ,item_archive_num ,sort_order ,
-- broadcast_date ,broadcast_time ,
-- channel_code ,channel_desc ,
-- broadcast_item_name ,item_title ,item_desc ,
-- Spokesman_str , Reference_str ,
-- digital_media_url,
-- barcode ,lush_broadcast_item_code,
-- file_cnt,play_cnt,file_code )
select top 101 dbo.broadcasts.broadcast_archive_num
, dbo.items.item_archive_num,items.sort_order
, dbo.broadcasts.broadcast_date,dbo.broadcasts.broadcast_time
,broadcast_items.channel_code,dbo.adm_channels.channel_desc
,isnull(broadcast_items.broadcast_item_name,dbo.broadcasts.program_title) as broadcast_item_name
--,dbo.items.item_title,dbo.items.item_desc
--,dbo.get_item_people_str(dbo.items.item_archive_num,'1') as Spokesman_str
--,dbo.get_item_people_str(dbo.items.item_archive_num,'0') as Reference_str
--,dbo.get_digital_media_url(@subnet,null,
-- dbo.get_item_0(broadcasts.broadcast_archive_num),null,null) as digital_media_url
--,dbo.barcodes.barcode,dbo.broadcasts.lush_broadcast_item_code
--,cnts.file_cnt,cnts.play_cnt
--,isnull(archive_files.file_code,
-- (select top 1 file_code
-- from dbo.archive_files
-- where item_archive_num= dbo.get_item_0(broadcasts.broadcast_archive_num)
-- and is_primary ='1' )) as file_code
from dbo.items inner join dbo.broadcasts
on dbo.broadcasts.broadcast_archive_num=dbo.items.broadcast_archive_num
left join
dbo.broadcast_items
on broadcast_items.broadcast_item_code=dbo.broadcasts.lush_broadcast_item_code left join
dbo.adm_channels
on dbo.adm_channels.channel_code=broadcast_items.channel_code
left join
dbo.broadcast_barcodes
on dbo.broadcast_barcodes.broadcast_archive_num=dbo.broadcasts.broadcast_archive_num
-- left join dbo.barcodes
--on dbo.barcodes.barcode=dbo.broadcast_barcodes.barcode
--left join dbo.archive_files
--on archive_files.item_archive_num=items.item_archive_num
-- and is_primary='1'
--left join dbo.digital_files
-- on digital_files.file_code=archive_files.file_code
--left join dbo.adm_code_media_file_types
-- on dbo.adm_code_media_file_types.media_file_type_code=digital_files.media_file_type_code
-- cross apply
-- (select file_cnt=count(*),play_cnt=isnull(sum(convert(tinyint,can_play)),0)
-- from dbo.archive_files
-- inner join dbo.digital_files
-- on digital_files.file_code=archive_files.file_code
-- inner join dbo.adm_code_media_file_types
-- on dbo.adm_code_media_file_types.media_file_type_code=digital_files.media_file_type_code
-- where archive_files.item_archive_num in
-- (items.item_archive_num,dbo.get_item_0(items.broadcast_archive_num) )) cnts
where items.net_code=2 and
--broadcasts.broadcast_date between @from_date and @to_date and
--(broadcast_items.channel_code =@channel or @channel is null) and
--(@has_digital_media is null or
-- (@has_digital_media= dbo.adm_code_media_file_types.can_play)) and
--(broadcast_items.broadcast_item_code in (select item from @bitems) or
-- @broadcast_items is null) and
--(@workers is null or items.item_archive_num in (select item_archive_num from item_workers
-- where (job_code =@job or @job is null)
-- and worker_code in
-- (select emp from @emps))) and
--(@topic is null or items.item_archive_num in (select item_archive_num from item_topics
-- where topic_code in
-- (select subjects from @topics))) and
--(@people is null or
-- items.item_archive_num in (select item_archive_num from item_people
-- where (( dbo.item_people.is_spokesman='1' and @inc_spokesman='1')
-- or
-- ( dbo.item_people.is_spokesman='0' and @inc_nonspokesman='1'))
-- and person_code in
-- (select guest from @guests))) and
(( @search_type=1
and (@word1=@junk
or contains(item_title, @word1a)
or contains(item_title, @word1b)
or contains(item_title, @word1c)
or contains(item_title, @word1d)
or contains(item_title, @word1e)
or contains(item_title, @word1f)
or contains(item_desc , @word1a)
or contains(item_desc , @word1b)
or contains(item_desc , @word1c)
or contains(item_desc , @word1d)
or contains(item_desc , @word1e)
or contains(item_desc , @word1f))
and (@word2=@junk
or contains(item_title, @word2a)
or contains(item_title, @word2b)
or contains(item_title, @word2c)
or contains(item_title, @word2d)
or contains(item_title, @word2e)
or contains(item_title, @word2f)
or contains(item_desc , @word2a)
or contains(item_desc , @word2b)
or contains(item_desc , @word2c)
or contains(item_desc , @word2d)
or contains(item_desc , @word2e)
or contains(item_desc , @word2f))
and (@word3=@junk
or contains(item_title, @word3a)
or contains(item_title, @word3b)
or contains(item_title, @word3c)
or contains(item_title, @word3d)
or contains(item_title, @word3e)
or contains(item_title, @word3f)
or contains(item_desc , @word3a)
or contains(item_desc , @word3b)
or contains(item_desc , @word3c)
or contains(item_desc , @word3d)
or contains(item_desc , @word3e)
or contains(item_desc , @word3f))
and (@word4=@junk
or contains(item_title, @word4a)
or contains(item_title, @word4b)
or contains(item_title, @word4c)
or contains(item_title, @word4d)
or contains(item_title, @word4e)
or contains(item_title, @word4f)
or contains(item_desc , @word4a)
or contains(item_desc , @word4b)
or contains(item_desc , @word4c)
or contains(item_desc , @word4d)
or contains(item_desc , @word4e)
or contains(item_desc , @word4f))
and (@word5=@junk
or contains(item_title, @word5a)
or contains(item_title, @word5b)
or contains(item_title, @word5c)
or contains(item_title, @word5d)
or contains(item_title, @word5e)
or contains(item_title, @word5f)
or contains(item_desc , @word5a)
or contains(item_desc , @word5b)
or contains(item_desc , @word5c)
or contains(item_desc , @word5d)
or contains(item_desc , @word5e)
or contains(item_desc , @word5f)))
or
(@search_type=2
and (contains(item_title, @ftext)
or contains(item_desc , @ftext)))
)
option(recompile)
--if isnull(@text,'')<>''
--insert into @res
--(broadcast_archive_num ,item_archive_num ,sort_order ,
-- broadcast_date ,broadcast_time ,
-- channel_code ,channel_desc ,
-- broadcast_item_name ,item_title ,item_desc ,
-- Spokesman_str , Reference_str ,
-- digital_media_url,
-- barcode ,lush_broadcast_item_code,
-- file_cnt,play_cnt,file_code )
-- select top 101 dbo.broadcasts.broadcast_archive_num
-- , dbo.items.item_archive_num,items.sort_order
-- , dbo.broadcasts.broadcast_date,dbo.broadcasts.broadcast_time
-- ,broadcast_items.channel_code,dbo.adm_channels.channel_desc
-- ,isnull(broadcast_items.broadcast_item_name,dbo.broadcasts.program_title) as broadcast_item_name
-- ,dbo.items.item_title,dbo.items.item_desc
-- ,dbo.get_item_people_str(dbo.items.item_archive_num,'1') as Spokesman_str
-- ,dbo.get_item_people_str(dbo.items.item_archive_num,'0') as Reference_str
-- ,dbo.get_digital_media_url(@subnet,null,
-- dbo.get_item_0(broadcasts.broadcast_archive_num),null,null) as digital_media_url
-- ,dbo.barcodes.barcode,dbo.broadcasts.lush_broadcast_item_code
-- ,cnts.file_cnt,cnts.play_cnt,archive_files.file_code
-- from dbo.items inner join dbo.broadcasts
-- on dbo.broadcasts.broadcast_archive_num=dbo.items.broadcast_archive_num left join
-- dbo.broadcast_items
-- on broadcast_items.broadcast_item_code=dbo.broadcasts.lush_broadcast_item_code left join
-- dbo.adm_channels
-- on dbo.adm_channels.channel_code=broadcast_items.channel_code left join
-- dbo.broadcast_barcodes
-- on dbo.broadcast_barcodes.broadcast_archive_num=dbo.broadcasts.broadcast_archive_num
-- left join dbo.barcodes
-- on dbo.barcodes.barcode=dbo.broadcast_barcodes.barcode
-- left join dbo.archive_files
-- on archive_files.item_archive_num=items.item_archive_num
-- and is_primary='1'
-- left join dbo.digital_files
-- on digital_files.file_code=archive_files.file_code
-- left join dbo.adm_code_media_file_types
-- on dbo.adm_code_media_file_types.media_file_type_code=digital_files.media_file_type_code
-- cross apply
-- (select file_cnt=count(*),play_cnt=isnull(sum(convert(tinyint,can_play)),0)
-- from dbo.archive_files
-- inner join dbo.digital_files
--on digital_files.file_code=archive_files.file_code
-- inner join dbo.adm_code_media_file_types
--on dbo.adm_code_media_file_types.media_file_type_code=digital_files.media_file_type_code
--where archive_files.item_archive_num in
-- (items.item_archive_num,dbo.get_item_0(items.broadcast_archive_num) )) cnts
--where items.net_code=2 and
-- broadcasts.broadcast_date between @from_date and @to_date and
-- (broadcast_items.channel_code =@channel or @channel is null) and
-- (@has_digital_media is null or
-- (@has_digital_media= dbo.adm_code_media_file_types.can_play)) and
-- (broadcast_items.broadcast_item_code in (select item from @bitems) or
-- @broadcast_items is null) and
-- (@workers is null or items.item_archive_num in (select item_archive_num from item_workers
-- where (job_code =@job or @job is null)
-- and worker_code in
-- (select emp from @emps))) and
-- (@topic is null or items.item_archive_num in (select item_archive_num from item_topics
-- where topic_code in
-- (select subjects from @topics))) and
-- (@people is null or
-- items.item_archive_num in (select item_archive_num from item_people
-- where (( dbo.item_people.is_spokesman='1' and @inc_spokesman='1')
-- or
-- ( dbo.item_people.is_spokesman='0' and @inc_nonspokesman='1'))
-- and person_code in
-- (select guest from @guests))) and
-- (( @search_type=1
-- and (@word1=@junk
-- or dbo.broadcasts.program_title like '%'+replace(@word1,'''''','''')+'%')
-- and (@word2=@junk
-- or dbo.broadcasts.program_title like '%'+replace(@word2,'''''','''')+'%')
-- and (@word3=@junk
-- or dbo.broadcasts.program_title like '%'+replace(@word3,'''''','''')+'%')
-- and (@word4=@junk
-- or dbo.broadcasts.program_title like '%'+replace(@word4,'''''','''')+'%')
-- and (@word5=@junk
-- or dbo.broadcasts.program_title like '%'+replace(@word5,'''''','''')+'%'))
-- or
-- (@search_type=2
-- and dbo.broadcasts.program_title ='%'+@text+'%')
-- )
--option(recompile)
--select item_list='item_list',* from @res
--select 'rows' as [rows],@@rowcount as row_cnt
--select 'topic_cnt' as topic_cnt,item_topics.topic_code,topic_desc,count(*) as cnt
-- from @res r inner join item_topics
-- on item_topics.item_archive_num=r.item_archive_num inner join
-- adm_code_topics
-- on adm_code_topics.topic_code=item_topics.topic_code
-- group by item_topics.topic_code,topic_desc,adm_code_topics.sort_order
-- order by count(*) desc,adm_code_topics.sort_order asc
END
???