September 13, 2010 at 9:09 am
Hi,
First of all, here are my tables :
CREATE TABLE [dbo].[Rank](
[R_id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[R_U_id] [int] NOT NULL,
[R_I_id] [int] NOT NULL,
[R_T_id] [int] NOT NULL,
[R_rank] [int] NULL,
CONSTRAINT [PK_Rank] PRIMARY KEY CLUSTERED
(
[R_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[Tag](
[A_id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[A_value] [nvarchar](128) NULL,
[A_flag_cat] [bit] NULL,
[A_lang] [nchar](2) NULL,
CONSTRAINT [PK__Tag__03317E3D] PRIMARY KEY CLUSTERED
(
[A_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[TopicTag](
[TT_id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[TT_A_id] [int] NOT NULL,
[TT_T_id] [int] NOT NULL,
[TT_U_id] [int] NOT NULL,
CONSTRAINT [PK_TopicTag] PRIMARY KEY CLUSTERED
(
[TT_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[TopicTag] WITH NOCHECK ADD CONSTRAINT [FK_TOPICTAG_REFERENCE_TAG] FOREIGN KEY([TT_A_id])
REFERENCES [dbo].[Tag] ([A_id])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[TopicTag] CHECK CONSTRAINT [FK_TOPICTAG_REFERENCE_TAG]
GO
ALTER TABLE [dbo].[TopicTag] WITH NOCHECK ADD CONSTRAINT [FK_TOPICTAG_REFERENCE_TOPIC] FOREIGN KEY([TT_T_id])
REFERENCES [dbo].[Topic] ([T_id])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[TopicTag] CHECK CONSTRAINT [FK_TOPICTAG_REFERENCE_TOPIC]
CREATE TABLE [dbo].[Topic](
[T_id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[T_value] [nvarchar](1000) NULL,
[T_language] [char](2) NULL,
[T_count] [bigint] NULL,
[T_lastModified] [datetime] NULL,
CONSTRAINT [PK__Topic__014935CB] PRIMARY KEY CLUSTERED
(
[T_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
I try to execute that simple query :
SELECT r_t_id, a_value
FROM rank
INNER JOIN topic on r_t_id = t_id
INNER JOIN topictag on t_id = tt_t_id
INNER JOIN tag on tt_a_id = a_id
WHERE t_id = 256
That query takes 16 seconds for 921954 lines returned. I have indexes on join criterias for each table. When I look a the execution plan, here is it :
In the INNER JOIN (94%) I have the following warning : NO JOIN PREDICATE. Why ?
Is there a way to optimize that query ?
Thanks in advance
September 13, 2010 at 9:39 am
Please post execution plan as a .sqlplan file as per http://www.sqlservercentral.com/articles/SQLServerCentral/66909/
Can you edit that query and qualify the join columns with their table names? Sounds like you've managed to create an accidental cross join. That's what the warning's saying.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
September 14, 2010 at 1:32 am
Hello, and thank you for your answer.
Here is the modified query with qualified tables and columns :
SELECT r.r_t_id, tg.a_value
FROM rank r
INNER JOIN topic tp on r.r_t_id = tp.t_id
INNER JOIN topictag tt on tp.t_id = tt.tt_t_id
INNER JOIN tag tg on tt.tt_a_id = tg.a_id
WHERE tp.t_id = 256
And I join the execution plan too, in .sqplan format.
Thank you very much for your help.
September 14, 2010 at 1:40 am
According to the execution plan there is no join predicate on the rank table to the others.
If you fully qualify the columns in the joins you should be able to identify the fault.
September 14, 2010 at 1:48 am
You have attached SQLPlan as per your old query. Use qualify names in the query and check performance & generate the execution plan.
Thanks
September 14, 2010 at 1:50 am
What plan do you get for
SELECT r_t_id--, a_value
FROM rank
INNER JOIN topic on rank.r_t_id = topic.t_id
--INNER JOIN topictag on t_id = tt_t_id
--INNER JOIN tag on tt_a_id = a_id
WHERE t_id = 256
September 14, 2010 at 3:40 am
frharkonnen (9/13/2010)
In the INNER JOIN (94%) I have the following warning : NO JOIN PREDICATE. Why ?
The top input of the inner join contains an index seek on Topic.t_id = 256. The bottom input contains an index seek on Rank.r_t_id = 256. So there's is no need for a join predicate. To put in in SQL, your query plan looks something like
SELECT r_t_id, a_value
FROM rank
CROSS JOIN topic
INNER JOIN topictag on t_id = tt_t_id
INNER JOIN tag on tt_a_id = a_id
WHERE t_id = 256
AND r_t_id = 256
Peter
September 15, 2010 at 2:37 am
Hi frharkonnen (maybe Feyd-Rautha?),
this is how I understand your schema:
Tag and Topic are master tables with a N:N relationship, TopicTag is the table that sustains this relationship. Rank is a table linked to Topic.
I feel your schema lacks on indexes. If TopicTag is a relationship table it needs a Topic+Tag index, or a Tag+Topic index, or both; for your query I feel you need an index by TT_T_id + TT_A_id.
Looking at table Rank you need also an index by R_T_id.
In your post the table Rank is unnecessary (I suppose you oversimplified your original query). That's your original query:
SELECT r_t_id, a_value
FROM rank
INNER JOIN topic on r_t_id = t_id
INNER JOIN topictag on t_id = tt_t_id
INNER JOIN tag on tt_a_id = a_id
WHERE t_id = 256
Here you select only a column from the Rank table, and this column belongs also to Topic table, so your query could be simplified as
SELECT t_id, a_value
FROM topic
INNER JOIN topictag on t_id = tt_t_id
INNER JOIN tag on tt_a_id = a_id
WHERE t_id = 256
I feel that implementing these indexes in your TopicTag table will improve your query execution.
Regards,
Francesc
September 15, 2010 at 9:25 am
frharkonnen (9/13/2010)
That query takes 16 seconds for 921954 lines returned
Returned to WHERE???? Find ANY table with almost a million lines in it and see how long it takes to return them to the screen. 😉
--Jeff Moden
Change is inevitable... Change for the better is not.
Viewing 9 posts - 1 through 8 (of 8 total)
You must be logged in to reply to this topic. Login to reply