By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,787 Members | 2,251 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,787 IT Pros & Developers. It's quick & easy.

slow sql update MS SQL 2000

P: n/a
I have the following statement that takes quite a long time. Longest
of any of my SQL statment updates.

UPDATE F_REGISTRATION_STD_SESSION
SET PREVIOUS_YEAR_SESSION_ID = (
SELECT s.previous_year_session_id
FROM F_REGISTRATION_STD_SESSION R
,DS_V4_TARGET.dbo.D_H_Session_By_SessQtr S
WHERE
r.STUDENT_ID = F_REGISTRATION_STD_SESSION.STUDENT_ID
and s.previous_year_SESSION_ID = r.SESSION_ID
and s.session_id = F_REGISTRATION_STD_SESSION.SESSION_ID
)
STUDENT_ID varchar(20) and SESSION_ID char(10) and are indexed
What I want to accomplish:
I want to know if there was a student registration from the prior year
of a registration.
Example, if there is a registration for Fall 2004, was there also a
registration for the same student Fall 2003?
Maybe there is a better way to approach this?
TIA
Rob
Jul 20 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
R Camarda (rc******@cablespeed.com) writes:
I have the following statement that takes quite a long time. Longest
of any of my SQL statment updates.

UPDATE F_REGISTRATION_STD_SESSION
SET PREVIOUS_YEAR_SESSION_ID = (
SELECT s.previous_year_session_id
FROM F_REGISTRATION_STD_SESSION R
,DS_V4_TARGET.dbo.D_H_Session_By_SessQtr S
WHERE
r.STUDENT_ID = F_REGISTRATION_STD_SESSION.STUDENT_ID
and s.previous_year_SESSION_ID = r.SESSION_ID
and s.session_id = F_REGISTRATION_STD_SESSION.SESSION_ID
)
STUDENT_ID varchar(20) and SESSION_ID char(10) and are indexed
What I want to accomplish:
I want to know if there was a student registration from the prior year
of a registration.
Example, if there is a registration for Fall 2004, was there also a
registration for the same student Fall 2003?
Maybe there is a better way to approach this?


It's difficult to tell without knowledge of the tables. It would help a
lot if you posted:

o CREATE TABLE statements for the two tables.
o All constraints and indexes for the table (As SQL statemets).
o INSERT statements with sample data.
o The desired output for the sample.
o The number of rows in each table.

The sample does not help to be big enough to demonstrate the problem,
only so that it helps to test a rewrite of the query.
--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Jul 20 '05 #2

P: n/a
Hi

Posting your ddl (Create table statements etc..) and example data (as insert
statements) would help in the solution of this problem. I think your
statement can be simplyfied to:

UPDATE R
SET PREVIOUS_YEAR_SESSION_ID = s.previous_year_session_id
FROM F_REGISTRATION_STD_SESSION R
JOIN DS_V4_TARGET.dbo.D_H_Session_By_SessQtr S ON s.session_id =
R.SESSION_ID
JOIN F_REGISTRATION_STD_SESSION P ON s.previous_year_session_id =
P.session_id
AND R.STUDENT_ID = P.STUDENT_ID

Look at the query plan to see if your indexes are being used, but you have
not given any indication on what is indexed on D_H_Session_By_SessQtr.

If your session_ids do not change between years then you should not need
D_H_Session_By_SessQtr but you will need to hold the year in
F_REGISTRATION_STD_SESSION.

John

"R Camarda" <rc******@cablespeed.com> wrote in message
news:d7**************************@posting.google.c om...
I have the following statement that takes quite a long time. Longest
of any of my SQL statment updates.

UPDATE F_REGISTRATION_STD_SESSION
SET PREVIOUS_YEAR_SESSION_ID = (
SELECT s.previous_year_session_id
FROM F_REGISTRATION_STD_SESSION R
,DS_V4_TARGET.dbo.D_H_Session_By_SessQtr S
WHERE
r.STUDENT_ID = F_REGISTRATION_STD_SESSION.STUDENT_ID
and s.previous_year_SESSION_ID = r.SESSION_ID
and s.session_id = F_REGISTRATION_STD_SESSION.SESSION_ID
)
STUDENT_ID varchar(20) and SESSION_ID char(10) and are indexed
What I want to accomplish:
I want to know if there was a student registration from the prior year
of a registration.
Example, if there is a registration for Fall 2004, was there also a
registration for the same student Fall 2003?
Maybe there is a better way to approach this?
TIA
Rob

Jul 20 '05 #3

P: n/a
// Connection: 3-Staging

CREATE TABLE "dbo"."F_Registration_STD_Session"
(
"REGISTRATION_KEY" VARCHAR(41) NULL,
"STUDENT_ID" VARCHAR(20) NULL,
"SESSION_ID" VARCHAR(20) NULL,
"LOAD_DT" DATETIME NULL,
"CLASS_ADD_COUNT" INTEGER NULL,
"CLASS_DROP_COUNT" INTEGER NULL,
"BEFORE_D0_CLASS_COUNT" INTEGER NULL,
"DAY0_CLASS_COUNT" INTEGER NULL,
"AFTER_D0_CLASS_COUNT" INTEGER NULL,
"ALL_CLASS_COUNT" INTEGER NULL,
"BEFORE_D0_ONLINE_CLASS_COUNT" INTEGER NULL,
"DAY0_ONLINE_CLASS_COUNT" INTEGER NULL,
"AFTER_D0_ONLINE_CLASS_COUNT" INTEGER NULL,
"ALL_ONLINE_CLASS_COUNT" INTEGER NULL,
"CLASS_NOSHOW_COUNT" INTEGER NULL,
"CLASS_WITHDRAW_COUNT" INTEGER NULL,
"COMPLETE_WITHDRAW_COUNT" INTEGER NULL,
"COMPLETE_NOSHOW_COUNT" INTEGER NULL,
"STUDENT_WITHDRAW_COUNT" INTEGER NULL,
"BEFORE_D0_ONLINE_ONLY_CLASS_CNT" INTEGER NULL,
"DAY0_ONLINE_ONLY_CLASS_COUNT" INTEGER NULL,
"AFTER_D0_ONLINE_ONLY_CLASS_COUNT" INTEGER NULL,
"ALL_ONLINE_ONLY_CLASS_COUNT" INTEGER NULL,
"SESSION_SKEY" INTEGER NULL,
"NEXT_REGISTERED_SESSION_SKEY" INTEGER NULL,
"PREV_REGISTERED_SESSION_SKEY" INTEGER NULL,
"SESSIONS_SKIPPED_NEXT" INTEGER NULL,
"SESSIONS_SKIPPED_PREV" INTEGER NULL,
"CLASS_ADD_DT" DATETIME NULL,
"CLASS_DROP_DT" DATETIME NULL,
"STUDENT_SKEY" INTEGER NULL,
"PREVIOUS_YEAR_SESSION_ID" VARCHAR(10) NULL,
"NEXT_YEAR_SESSION_ID" VARCHAR(10) NULL,
"CAMPUS_SKEY" INTEGER NULL,
"ACTIVITY_DT" DATETIME NULL,
"CAMPUS_ID" VARCHAR(2) NULL
)

CREATE INDEX ix1F_Registration_STD_Session ON
"dbo"."F_Registration_STD_Session" ( "STUDENT_ID" );
CREATE INDEX ix2F_Registration_STD_Session ON
"dbo"."F_Registration_STD_Session" ( "SESSION_ID" );
CREATE INDEX ix3F_Registration_STD_Session ON
"dbo"."F_Registration_STD_Session" ( "NEXT_REGISTERED_SESSION_SKEY" );
CREATE INDEX ix4F_Registration_STD_Session ON
"dbo"."F_Registration_STD_Session" ( "PREV_REGISTERED_SESSION_SKEY" );
CREATE INDEX ix5F_Registration_STD_Session ON
"dbo"."F_Registration_STD_Session" ( "STUDENT_SKEY" );
CREATE INDEX ix6F_Registration_STD_Session ON
"dbo"."F_Registration_STD_Session" ( "PREVIOUS_YEAR_SESSION_ID" );
CREATE INDEX ix7F_Registration_STD_Session ON
"dbo"."F_Registration_STD_Session" ( "NEXT_YEAR_SESSION_ID" );
CREATE INDEX ix8F_Registration_STD_Session ON
"dbo"."F_Registration_STD_Session" ( "CAMPUS_SKEY" );
CREATE INDEX STUDENT_ID ON "dbo"."F_Registration_Session_Lookup" (
"STUDENT_ID" );
CREATE INDEX SESSION_ID ON "dbo"."F_Registration_Session_Lookup" (
"SESSION_ID" )

CREATE TABLE "dbo"."D_H_Session_By_SessQtr"
(
"SESSION_SKEY" INTEGER NULL,
"SESSION_CAPTION" VARCHAR(19) NULL,
"SESSION_ID" VARCHAR(20) NULL,
"SESSION_YEAR" VARCHAR(20) NULL,
"SESSION_START_DT" DATETIME NULL,
"SESSION_END_DT" DATETIME NULL,
"SESSION_AddDrop_DT" DATETIME NULL,
"SESSION_DROP_DT" DATETIME NULL,
"SESSION_PNOTE_DUE1_DT" DATETIME NULL,
"SESSION_PNOTE_DUE2_DT" DATETIME NULL,
"SESSION_PNOTE_DUE3_DT" DATETIME NULL,
"SESSION_QTR" VARCHAR(20) NULL,
"SESSION_QTR_CAPTION" VARCHAR(23) NULL,
"All_id" VARCHAR(3) NULL,
"All_caption" VARCHAR(21) NULL,
"SESSION_ID_CAPTION" VARCHAR(50) NULL,
"PREVIOUS_SESSION_ID" VARCHAR(10) NULL,
"NEXT_SESSION_ID" VARCHAR(10) NULL,
"PREVIOUS_SESSION_SKEY" NUMERIC(19) NULL,
"NEXT_SESSION_SKEY" NUMERIC(19) NULL,
"PREVIOUS_YEAR_SESSION_ID" VARCHAR(10) NULL,
"NEXT_YEAR_SESSION_ID" VARCHAR(10) NULL,
"PREVIOUS_YEAR_SESSION_SKEY" NUMERIC(19) NULL,
"NEXT_YEAR_SESSION_SKEY" NUMERIC(19) NULL
)
;
CREATE INDEX ix1D_H_Session_By_SessQtr ON
"dbo"."D_H_Session_By_SessQtr" ( "SESSION_SKEY" );
CREATE INDEX ix2D_H_Session_By_SessQtr ON
"dbo"."D_H_Session_By_SessQtr" ( "SESSION_QTR" );
CREATE INDEX ix3D_H_Session_By_SessQtr ON
"dbo"."D_H_Session_By_SessQtr" ( "All_id" );
CREATE INDEX PREVIOUS_YEAR_SESSION_ID ON
"dbo"."D_H_Session_By_SessQtr" ( "PREVIOUS_YEAR_SESSION_ID" );
CREATE INDEX NEXT_YEAR_SESSION_ID ON "dbo"."D_H_Session_By_SessQtr" (
"NEXT_YEAR_SESSION_ID" )

[EXECUTEDSQ - 07:23:54] data insert

insert into "dbo"."F_Registration_STD_Session" ("REGISTRATION_KEY",
"STUDENT_ID", "SESSION_ID", "LOAD_DT", "CLASS_ADD_COUNT",
"CLASS_DROP_COUNT", "BEFORE_D0_CLASS_COUNT", "DAY0_CLASS_COUNT",
"AFTER_D0_CLASS_COUNT", "ALL_CLASS_COUNT",
"BEFORE_D0_ONLINE_CLASS_COUNT", "DAY0_ONLINE_CLASS_COUNT",
"AFTER_D0_ONLINE_CLASS_COUNT", "ALL_ONLINE_CLASS_COUNT",
"CLASS_NOSHOW_COUNT", "CLASS_WITHDRAW_COUNT",
"COMPLETE_WITHDRAW_COUNT", "COMPLETE_NOSHOW_COUNT",
"STUDENT_WITHDRAW_COUNT", "BEFORE_D0_ONLINE_ONLY_CLASS_CNT",
"DAY0_ONLINE_ONLY_CLASS_COUNT", "AFTER_D0_ONLINE_ONLY_CLASS_COUNT",
"ALL_ONLINE_ONLY_CLASS_COUNT", "SESSION_SKEY",
"NEXT_REGISTERED_SESSION_SKEY", "PREV_REGISTERED_SESSION_SKEY",
"SESSIONS_SKIPPED_NEXT", "SESSIONS_SKIPPED_PREV", "CLASS_ADD_DT",
"CLASS_DROP_DT", "STUDENT_SKEY", "PREVIOUS_YEAR_SESSION_ID",
"NEXT_YEAR_SESSION_ID", "CAMPUS_SKEY", "ACTIVITY_DT", "CAMPUS_ID")
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

[EXECUTEDSQ - 07:26:20] checking existing Dimension table rows

select "SESSION_SKEY", "SESSION_CAPTION", "SESSION_ID",
"SESSION_YEAR", "SESSION_START_DT", "SESSION_END_DT",
"SESSION_AddDrop_DT", "SESSION_DROP_DT", "SESSION_PNOTE_DUE1_DT",
"SESSION_PNOTE_DUE2_DT", "SESSION_PNOTE_DUE3_DT", "SESSION_QTR",
"SESSION_QTR_CAPTION", "All_id", "All_caption", "SESSION_ID_CAPTION",
"PREVIOUS_SESSION_ID", "NEXT_SESSION_ID", "PREVIOUS_SESSION_SKEY",
"NEXT_SESSION_SKEY", "PREVIOUS_YEAR_SESSION_ID",
"NEXT_YEAR_SESSION_ID", "PREVIOUS_YEAR_SESSION_SKEY",
"NEXT_YEAR_SESSION_SKEY" from "dbo"."D_H_Session_By_SessQtr"
Jul 20 '05 #4

P: n/a
R Camarda (rc******@cablespeed.com) writes:
// Connection: 3-Staging

CREATE TABLE "dbo"."F_Registration_STD_Session"


Thanks for the tables and indexes. Unfortunately the INSERT statment
had only placeholders, so it was not useful. I would have need a couple
(2-3) rows in each table. And of course the desired result.

One thing which is missing are the PRIMARY KEY constraints. Don't you
have any? Given the index you posted, I would not expect anyone of them
to be used, since they are all non-clustered. I would expect the optimizer
to scan all three tables and then perform a hash-join.

If you add a composite, non-clustered, index on (previous_year_SESSION_ID,
SESSION_ID) on D_H_Session_By_SessQtr, that index would be a covering index
for the query. In the same vein a non-clustered index (SESSION_ID,
STUDENT_ID) for F_REGISTRATION_STD_SESSION could also help. Note here that I
have listed the potential index columns in arbitrary order. It may be better
to flip them; you will have to test.

Did you try the rewrite that John Bell suggested? (That too would benefit
from the covering indexes.)
--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Jul 20 '05 #5

P: n/a
John, I tried your example; it worked, kind of.
student_id session_id previous_session_id
000004561 200403 000000
000004561 200404 000000
000005131 200002 000000
000005131 200003 000000
000005131 200004 000000
000005131 200102 200002
000005131 200103 200003
000005131 200104 200004
000005131 200202 200102
000005131 200203 200103
000005131 200204 200104
000005131 200302 200202
000005131 200303 200203
000005131 200304 200204
000005131 200402 200302
000005131 200403 200303
000005131 200404 200304
000005131 200502 200402

I have updates that I will post..
Thanks

"John Bell" <jb************@hotmail.com> wrote in message news:<41***********************@news.easynet.co.uk >...
Hi

Posting your ddl (Create table statements etc..) and example data (as insert
statements) would help in the solution of this problem. I think your
statement can be simplyfied to:

UPDATE R
SET PREVIOUS_YEAR_SESSION_ID = s.previous_year_session_id
FROM F_REGISTRATION_STD_SESSION R
JOIN DS_V4_TARGET.dbo.D_H_Session_By_SessQtr S ON s.session_id =
R.SESSION_ID
JOIN F_REGISTRATION_STD_SESSION P ON s.previous_year_session_id =
P.session_id
AND R.STUDENT_ID = P.STUDENT_ID

Look at the query plan to see if your indexes are being used, but you have
not given any indication on what is indexed on D_H_Session_By_SessQtr.

If your session_ids do not change between years then you should not need
D_H_Session_By_SessQtr but you will need to hold the year in
F_REGISTRATION_STD_SESSION.

John

Jul 20 '05 #6

P: n/a
The orignal message took awhile to post, so I did more work in the
mean time.
For testing, I added
WHILE SESSION_ID = '200502'

to restrict the amount of rows it had to process. I turned on
EXECUTION PLAN in Query Analyzer. I recall it spent a ton of time in
the subquery, so I decided to create a "lookup" tables that contained
just STUDENT_ID and SESSION_ID.
This is the query I got to work:

UPDATE F_REGISTRATION_STD_SESSION
SET PREVIOUS_YEAR_SESSION_ID = (
SELECT s.previous_year_session_id
FROM F_Registration_Session_Lookup R, D_Session S
WHERE
r.STUDENT_ID = F_REGISTRATION_STD_SESSION.STUDENT_ID
and s.previous_year_SESSION_ID = r.SESSION_ID
and s.session_id = F_REGISTRATION_STD_SESSION.SESSION_ID
)
;
I also made the necessary changed to the D_SESSION table by adding
PREVIOUS_SESSION_ID. At one point, I thought using two different
tables might be impacting me. Once I made the table change and ran my
original query, it did not change the time, so I moved ahead with the
lookup table.

D_SESSION and dbo.D_H_Session_By_SessQtr are nearly the same.
D_SESSION is just session information and dbo.D_H_Session_By_SessQtr
adds hierarchy of Session quarter's.
rc******@cablespeed.com (R Camarda) wrote in message
news:<d7**************************@posting.google. com>...
I have the following statement that takes quite a long time. Longest
of any of my SQL statment updates.

UPDATE F_REGISTRATION_STD_SESSION
SET PREVIOUS_YEAR_SESSION_ID = (
SELECT s.previous_year_session_id
FROM F_REGISTRATION_STD_SESSION R
,DS_V4_TARGET.dbo.D_H_Session_By_SessQtr S
WHERE
r.STUDENT_ID = F_REGISTRATION_STD_SESSION.STUDENT_ID
and s.previous_year_SESSION_ID = r.SESSION_ID
and s.session_id = F_REGISTRATION_STD_SESSION.SESSION_ID
)
STUDENT_ID varchar(20) and SESSION_ID char(10) and are indexed
What I want to accomplish:
I want to know if there was a student registration from the prior year
of a registration.
Example, if there is a registration for Fall 2004, was there also a
registration for the same student Fall 2003?
Maybe there is a better way to approach this?
TIA
Rob

Jul 20 '05 #7

P: n/a
Erland,
I am usings a Data warehouse tool from Cognos called DecisionStream. I
only delve into SQL when I need to do something that cant be done
inside the tool.
I checked SQL Server Enterprise Manager to look for the primary keys,
and I did not find any. (I looked in DESIGN TABLE and did not find the
Key icon on my primary key). The primary key for D_SESSION is
SESSION_SKEY. This is used instead of SESSION_ID. The table,
F_Registration_STD_Session key's are STUDENT_ID (or STUDENT_SKEY) and
SESSION_ID ( or SESSION_SKEY), I'm not sure how a composite key or
index would work.
My basic approach is to make sure anything I'm join by, has an index.
I've not used or set primary keys nor used composite keys outside of
DecisionStream. (Notice there is REGISTRATION_KEY which is
STUDENT_ID*SESSION_ID. I use this inside the tool)
I feel that I have an opportunity to expand my knowledge of SQL based
on this thread that will help me in the future.
Comments welcome.
Thanks
Rob
Erland Sommarskog <es****@sommarskog.se> wrote in message news:<Xn**********************@127.0.0.1>...
R Camarda (rc******@cablespeed.com) writes:
// Connection: 3-Staging

CREATE TABLE "dbo"."F_Registration_STD_Session"


Thanks for the tables and indexes. Unfortunately the INSERT statment
had only placeholders, so it was not useful. I would have need a couple
(2-3) rows in each table. And of course the desired result.

One thing which is missing are the PRIMARY KEY constraints. Don't you
have any? Given the index you posted, I would not expect anyone of them
to be used, since they are all non-clustered. I would expect the optimizer
to scan all three tables and then perform a hash-join.

If you add a composite, non-clustered, index on (previous_year_SESSION_ID,
SESSION_ID) on D_H_Session_By_SessQtr, that index would be a covering index
for the query. In the same vein a non-clustered index (SESSION_ID,
STUDENT_ID) for F_REGISTRATION_STD_SESSION could also help. Note here that I
have listed the potential index columns in arbitrary order. It may be better
to flip them; you will have to test.

Did you try the rewrite that John Bell suggested? (That too would benefit
from the covering indexes.)

Jul 20 '05 #8

P: n/a
There are many columns for D_SESSION, so I'll just post the fields I'm
using

Data for D_SESSION
session_skey session_id previous_year_session_id
------------ -------------------- ------------------------
291 200002 199902
292 200003 199903
293 200004 199904
294 200005 199905
295 200102 200002
296 200103 200003
297 200104 200004
298 200105 200005
299 200202 200102
300 200203 200103

session_skey is int
session_id is varchar(10)
previous_year_session_id is varchar(10)
Indexes on session_skey, session_id and previous_year_session_id

Here is a complete single row:
SESSION_SKEY SESSION_ID SESSION_CAPTION SESSION_YEAR
SESSION_QTR SESSION_START_DT
SESSION_END_DT
SESSION_AddDrop_DT SESSION_DROP_DT
SESSION_PNOTE_DUE1_DT
SESSION_PNOTE_DUE2_DT
SESSION_PNOTE_DUE3_DT eff_date
end_date
cre_date
udt_date
curr_ind SESSION_ID_CAPTION
PREVIOUS_YEAR_SESSION_ID NEXT_YEAR_SESSION_ID
------------ -------------------- -------------------
-------------------- --------------------
------------------------------------------------------
------------------------------------------------------
------------------------------------------------------
------------------------------------------------------
------------------------------------------------------
------------------------------------------------------
------------------------------------------------------
------------------------------------------------------
------------------------------------------------------
------------------------------------------------------
------------------------------------------------------ --------
--------------------------------------------------
------------------------ --------------------
291 200002 Fall Quarter 1999 2000
02 1999-09-27 00:00:00.000
1999-12-19 00:00:00.000
1999-10-04 00:00:00.000 1999-11-12
00:00:00.000 1999-09-13 00:00:00.000
1999-10-13 00:00:00.000
1999-11-12 00:00:00.000
2004-07-20 00:00:00.000 NULL
2004-07-20 11:45:39.000
2004-09-03 22:10:33.000
Y 200002 Fall Quarter 1999
199902 200102

Everthing is either DATETIME, varchar(). SESSION_SKEY is INT

Sample of f_registration_std_session
registration_key student_id student_skey session_id session_skey
previous_year_session_id
---------------- ---------- ------------ ---------- ------------
------------------------
999970104*200202 999970104 408515 200202 299
200102
999970104*200105 999970104 408515 200105 298
200005
999970104*200104 999970104 408515 200104 297
200004
999970104*200103 999970104 408515 200103 296
200003
999970104*200102 999970104 408515 200102 295
200002
999970104*200005 999970104 408515 200005 294 NULL
999970104*200004 999970104 408515 200004 293 NULL
999970104*200003 999970104 408514 200003 292 NULL
999970104*200002 999970104 408514 200002 291 NULL

only session_skey is int, everything else is char.
Jul 20 '05 #9

P: n/a
R Camarda (rc******@cablespeed.com) writes:
I checked SQL Server Enterprise Manager to look for the primary keys,
and I did not find any. (I looked in DESIGN TABLE and did not find the
Key icon on my primary key). The primary key for D_SESSION is
SESSION_SKEY. This is used instead of SESSION_ID. The table,
F_Registration_STD_Session key's are STUDENT_ID (or STUDENT_SKEY) and
SESSION_ID ( or SESSION_SKEY), I'm not sure how a composite key or
index would work.
CREATE INDEX composite_index ON tbl(SESSION_ID, STUDENT_ID)
My basic approach is to make sure anything I'm join by, has an index.


But that is not a very constructive strategy. Just because there is an
index, does not mean that it is useful. For simplicity consider
the question

SELECT * FROM tbl WHERE col = 10

There is a non-clustered index on col, and about 10% of the rows has
the value 10. Is tnis index useful for the query? Probably not. For
every hit in the index, SQL Server has to go the data page and get
the data. Since there can be many rows on the a data page, it may mean
that SQL Server reads the same row more than once. So it concludes it's
better to scane the table instead.

With a clustered index, the story is completely different. Here the
leaf level of the index is the data, so using the index is very
effecient.

Now consider the query:

SELECT SUM(clust) FROM tbl WHERE col = 10

Again, there is a non-clustered index on col and clustered index on clust.
In this case, SQL Server will use the non-clustered index. This is because
in a non-clustered index, the clustered index serves as row locator. So
clust is in fact in that index, and there is no need to access the data
pages. This is a covered query.

Your tables does not have any clustered indexes, and neither any primary
keys, so they are definitely difficult to deal with. (With a clustered
index, an internal rowid serves as row locator.)

What is the best index depends from situation to situation. It is not
always an idea to add a covering index (for instance because table
columns are being accessed anyway). In this case, it seems very useful,
becaue the tables has many columns, but the query only access a few.

--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Jul 20 '05 #10

P: n/a

Hi

To add to Erlands replies, you may also find some help from the Index
Tuning Wizard, that is on the Query menu of Query Analyser. Although
this does not take into account other statements where your table is
used (you can actually make performance slower if you specifically gear
your tuning to a single query!!) it may give you a better starting
point.

The Index Tuning Wizard can also be used against the output of SQL
Server Profiler. If this is run for a period of time, the Index Tuning
Wizard will have more information to make it recomendations.

John

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Jul 20 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.