Showing posts with label optimize. Show all posts
Showing posts with label optimize. Show all posts

Monday, March 19, 2012

Help with a Query

Is there a way to optimize this query, by doing it in fewer steps?
Perhaps by only utilizing and updating one table?
-TIA-
code:

/ ****************************************
****
Import the data from DBCC SQLPERF(LOGSPACE)
****************************************
****/
CREATE TABLE #dbcc_sqlperf (
DB_Name varchar(100),
Log_Size decimal (28, 5),
Log_Used_Percent decimal (28, 5),
Status tinyint )
INSERT #dbcc_sqlperf EXEC ('DBCC SQLPERF(LOGSPACE) WITH NO_INFOMSGS')
SELECT * FROM #dbcc_sqlperf --Debug
/ ****************************************
****
Convert the data form DBCC SQLPERF(LOGSPACE)
into a more legible form
****************************************
****/
CREATE TABLE #logstats (
DB_ID tinyint,
DB_Name varchar(100),
Logical_Name varchar(100),
File_Type varchar(10),
Total_Space_in_MB decimal (28, 2),
Used_Space_in_MB decimal (28, 2),
Free_Space_in_MB decimal (28, 2),
Percent_Used decimal (28, 2))
INSERT #logstats (DB_Name, File_Type, Total_Space_in_MB,
Used_Space_in_MB,
Free_Space_in_MB, Percent_Used)
SELECT DB_Name = DB_Name,
File_Type = 'Log',
Total_Space_in_MB = log_size,
Used_Space_in_MB = sum (log_size*(log_used_percent/100)),
Free_Space_in_MB = sum (log_size
-(log_size*(log_used_percent/100))),
Percent_Used = log_used_percent
FROM #dbcc_sqlperf
GROUP BY DB_Name, Log_Size, Log_Used_Percent, Status
/ ****************************************
****
Collect the DBID number for each log file
****************************************
****/
UPDATE l
SET DB_ID = m.dbid
FROM #logstats l INNER JOIN master..sysdatabases m
ON m.name = l.DB_Name
/ ****************************************
****
colloct the Logical Name for each log file
****************************************
****/
UPDATE l
SET Logical_Name = m.name
FROM #logstats l INNER JOIN master..sysaltfiles m
ON m.dbid = l.DB_ID AND m.groupid = '0'
/ ****************************************
****
Display and drop temp tables
****************************************
****/
SELECT * FROM #logstats
DROP TABLE #logstats
DROP TABLE #dbcc_sqlperf

What exactly do you expect this script to do? What are you trying to
accomplish?
Anith|||This is a small snippet of a larger project that you can find at
http://groups.google.com/group/micr...939daf22f9796b8
Anyway the idea behind this is to continually (every 15 minutes or so)
go out to all the servers and collect the statistics of the databases.
This will then be stored in a centralized location where we can tract
trends, and or raise alarms if some of our developers do a bulk insert
(with out tell us of course). I just would like to do it the most
efficient way the first time. If I can reduce the I/O's and CPU by
even a couple of points then its worth it.
I think I tend to scare everyone off when I post a huge chunk of code,
so i am doing it piecemeal
Thanks
-Matt-|||>> I think I tend to scare everyone off when I post a huge chunk of code,
Of course you are :-)
Try creating a script & schedule it to run every 15 minutes and insert the
results into a permanent base table. Here is a simple re-write without
changing much of what you posted:
CREATE TABLE #dbcc_sqlperf (
database_name VARCHAR(40), Log_Size DECIMAL (28, 5),
Log_Used_Percent DECIMAL (28, 5), Status TINYINT );
INSERT #dbcc_sqlperf EXEC ('DBCC SQLPERF(LOGSPACE) WITH NO_INFOMSGS')
SELECT DB_ID( database_name ) AS "database_id",
database_name AS "database_name",
( SELECT m.name
FROM master..sysaltfiles m
WHERE m.dbid = DB_ID(l.database_name)
AND m.groupid = '0' ) AS "logical file name",
'Log' AS "file_type",
log_size AS "total space in MB",
SUM (log_size * log_used_percent * .001) AS "used space in MB",
SUM (log_size - (log_size * log_used_percent * .001)) AS "free space
in MB",
log_used_percent AS "percent used"
FROM #dbcc_sqlperf l
GROUP BY database_name, Log_Size, Log_Used_Percent, Status ;
You can use a table variable to avoid temp table usage. Alternatively, you
may be able to retrieve similar information using the system procedure
sp_spaceused as well.
Anith|||Thanks Anith,
I really appreciate this. I am always looking to speed up and
bulletproof my code. if i can save a few extra cycles, during the
lifetime code that will run, could be several hours. Sure this might be
trivial, but if I reuse this code somewhere I know that I have one of
the most efficient pieces premade.

Wednesday, March 7, 2012

Help to optimize query

Hi,
I have these two tables in a Database

ITEMS
IDnumeric (Primary key)
ZDIDnvarchar 3 (not null)
IDF_Familynumeric(not null)
Descriptionnvarchar40 (not null)

DATAS
IDnumeric(Primary Key)
IDF_Itemnumeric(Foreign key)
IDF_Referencenumeric(Foreign Key)
[Date]smalldatetime(not null)
Containernchar10(not null)
Averagedecimal(not null)
[%Compliance]decimal(not null)
[%OutOfRange<MinTg]decimal(not null)
[%OutOfRange>MaxTg]decimal(not null)
Targetdecimal(not null)
[Min]decimal(not null)
[Max]decimal(not null)

The table DATAS has 4000000+ records

I'm running this query:

SELECT DISTINCT I.ID, I.ZDID, I.IDF_Family, I.Description
FROM Items as I, Datas as D
WHERE D.IDF_Item = I.ID AND I.IDF_Family = 84
AND D.Date BETWEEN '5/18/2004' AND '5/18/2004'

it's taking 4-5 minutes to run.
The result is correct, there is no thing on that date.
I've done a reindex, but still the same thing.

What can I do?

Thanksbie2 (Francois.Tardif@.gmail.com) writes:
> I have these two tables in a Database
> ITEMS
> ID numeric (Primary key)
> ZDID nvarchar 3 (not null)
> IDF_Family numeric (not null)
> Description nvarchar 40 (not null)
> DATAS
> ID numeric (Primary Key)
> IDF_Item numeric (Foreign key)
> IDF_Reference numeric (Foreign Key)
> [Date] smalldatetime (not null)
> Container nchar 10 (not null)
> Average decimal (not null)
> [%Compliance] decimal (not null)
> [%OutOfRange<MinTg] decimal (not null)
> [%OutOfRange>MaxTg] decimal (not null)
> Target decimal (not null)
> [Min] decimal (not null)
> [Max] decimal (not null)
>
> The table DATAS has 4000000+ records
> I'm running this query:
> SELECT DISTINCT I.ID, I.ZDID, I.IDF_Family, I.Description
> FROM Items as I, Datas as D
> WHERE D.IDF_Item = I.ID AND I.IDF_Family = 84
> AND D.Date BETWEEN '5/18/2004' AND '5/18/2004'
> it's taking 4-5 minutes to run.
> The result is correct, there is no thing on that date.
> I've done a reindex, but still the same thing.

A shot in the dark: change 84 to convert(numeric, 84). If that does not
cut it, please answer the questions below:

How many rows are there in Items?

Exactly what indexes are there on the table? Please indicate which
indexes that are clustered.

Can you run the query preceeded by SET STATISTICS PROFILE ON, and
post the output?

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pr...oads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodin...ions/books.mspx|||>A shot in the dark: change 84 to convert(numeric, 84). If that does not
>cut it, please answer the questions below:
Nothing changed.

>How many rows are there in Items?
30

>Exactly what indexes are there on the table? Please indicate which
>indexes that are clustered.
On DATAS ID is a clustered Index

>Can you run the query preceeded by SET STATISTICS PROFILE ON, and
>post the output?
01SELECT DISTINCT I.ID, I.ZDID, I.IDF_Family, I.Description FROM
Items as I, Datas as D WHERE D.IDF_Item = I.ID AND I.IDF_Family =
convert(numeric, 84) AND D.Date BETWEEN '5/18/2006' AND
'5/18/2006'210NULLNULLNULLNULL18.225489NULLNULLNULL63.874825NULLNULLSELECT0NULL
01 |--Nested Loops(Inner Join, OUTER
REFERENCES:([D].[IDF_Item]))231Nested LoopsInner JoinOUTER
REFERENCES:([D].[IDF_Item])NULL18.2262020.07.6185526E-511063.874825[I].[Description],
[I].[IDF_Family], [I].[ZDID], [I].[ID]NULLPLAN_ROW01.0
01 |--Sort(DISTINCT ORDER BY:([D].[IDF_Item]
ASC))243SortDistinct SortDISTINCT ORDER BY:([D].[IDF_Item]
ASC)NULL18.2262021.1261261E-24.4788996E-41663.866585[D].[IDF_Item]NULLPLAN_ROW01.0
01 | |--Clustered Index
Scan(OBJECT:([AccessReporting].[dbo].[Datas].[PK_Data] AS [D]),
WHERE:([D].[Date]='May 18 2006 12:00AM'))254Clustered Index
ScanClustered Index
ScanOBJECT:([AccessReporting].[dbo].[Datas].[PK_Data] AS [D]),
WHERE:([D].[Date]='May 18 2006 12:00AM')[D].[Date],
[D].[IDF_Item]41.49002556.7212834.96644977861.687733[D].[Date],
[D].[IDF_Item]NULLPLAN_ROW01.0
00 |--Clustered Index
Seek(OBJECT:([AccessReporting].[dbo].[Items].[PK_Items] AS [I]),
SEEK:([I].[ID]=[D].[IDF_Item]), WHERE:([I].[IDF_Family]=84) ORDERED
FORWARD)263Clustered Index SeekClustered Index
SeekOBJECT:([AccessReporting].[dbo].[Items].[PK_Items] AS [I]),
SEEK:([I].[ID]=[D].[IDF_Item]), WHERE:([I].[IDF_Family]=84) ORDERED
FORWARD[I].[Description], [I].[IDF_Family], [I].[ZDID],
[I].[ID]1.06.3284999E-37.9603E-51018.1532737E-3[I].[Description],
[I].[IDF_Family], [I].[ZDID], [I].[ID]NULLPLAN_ROW018.226202|||Tried this simple query

SELECT D.ID
FROM Datas as D
WHERE D.Date BETWEEN '5/18/2006' AND '5/18/2006'

And still took me 3 minutes, So maybe the problem is with the index on
DATAS|||Solved Created a non clustered index for Date and IDF_Items.