Solved

SQL Server String Performance

Posted on 2014-09-15
11
283 Views
Last Modified: 2014-09-17
Hello, I have the following SQL Server string:

SELECT DISTINCT 
                      TOP (40) dbo.DDB.brandname, SQRT(POWER(dbo.DDB.latitude - 29.935313, 2) 
                      + POWER(dbo.DDB.longitude - (-90.068825), 2)) / 0.014457 AS Expr1, dbo.DDB.locationName, 
                      dbo.DDB.streetLine1, dbo.DDB.city, dbo.DDB.state, dbo.DDB.postalCode, 
                      dbo.DDB.brandLogoName, dbo.DDB.locationIdentifier, dbo.DDB.offerIdentifier, 
                      dbo.DDB.description, dbo.DDB.categoryIdentifier, dbo.DDB.source
FROM         dbo.DDB INNER JOIN
                      dbo.CATEGORY_LINKS ON dbo.DDB.categoryIdentifier = dbo.CATEGORY_LINKS.LinkedCategory
WHERE     (dbo.DDB.maxprints > dbo.DDB.prints) AND (SQRT(POWER(dbo.DDB.latitude - 29.935313, 2) 
                      + POWER(dbo.DDB.longitude - (-90.068825), 2)) / 0.014457 BETWEEN 0 AND 20)

Open in new window


This Works perfect, but when I add the line ORDER BY Expr1 at the end, the performance decreases a lot, actually, the CPU usage jumps to 30%.

Is there a way to sort the results without losing performance?

Thanks
0
Comment
Question by:SimpleDude
  • 3
  • 2
  • 2
  • +3
11 Comments
 
LVL 13

Expert Comment

by:Russell Fox
ID: 40324081
Could you persist this data as a computed column in the DDB database?

http://msdn.microsoft.com/en-us/library/ms188300(v=sql.105).aspx
0
 

Author Comment

by:SimpleDude
ID: 40324097
Hi Russell,

I cannot set a computed column cause 0.014457  and -90.068825 are variables that change almost on every user click.

Thanks!
0
 
LVL 1

Expert Comment

by:Sleepydog
ID: 40324177
What if you persist this data into a #tempTable, then use your order by in the temp table? Not sure if this is the correct syntax but here goes...

 SELECT DISTINCT 
                      TOP (40) dbo.DDB.brandname, SQRT(POWER(dbo.DDB.latitude - 29.935313, 2) 
                      + POWER(dbo.DDB.longitude - (-90.068825), 2)) / 0.014457 AS Expr1, dbo.DDB.locationName, 
                      dbo.DDB.streetLine1, dbo.DDB.city, dbo.DDB.state, dbo.DDB.postalCode, 
                      dbo.DDB.brandLogoName, dbo.DDB.locationIdentifier, dbo.DDB.offerIdentifier, 
                      dbo.DDB.description, dbo.DDB.categoryIdentifier, dbo.DDB.source
INTO #TempTable
FROM         dbo.DDB INNER JOIN
                      dbo.CATEGORY_LINKS ON dbo.DDB.categoryIdentifier = dbo.CATEGORY_LINKS.LinkedCategory
WHERE     (dbo.DDB.maxprints > dbo.DDB.prints) AND (SQRT(POWER(dbo.DDB.latitude - 29.935313, 2) 
                      + POWER(dbo.DDB.longitude - (-90.068825), 2)) / 0.014457 BETWEEN 0 AND 20)

SELECT * FROM #TempTable
ORDER BY Expr1
 

Open in new window

0
 

Author Comment

by:SimpleDude
ID: 40324223
Hi Sleepy, thanks for the reply. I tried that solution before but the result is sort of the same.
0
 
LVL 13

Expert Comment

by:Russell Fox
ID: 40324342
You can try creating a new nonclustered index on ([DDB_ID], [Latitude], [Longitude]), and then create a function that uses the new index and can be called in your query:
CREATE FUNCTION fGetLatLon
(
	@Lat FLOAT,
	@Lon FLOAT,
	@Factor FLOAT,
	@DDBID INT
)
RETURNS FLOAT
AS
BEGIN

	DECLARE @LatLon FLOAT

	SELECT @LatLon = SQRT(POWER(dbo.DDB.latitude - @Lat, 2) + POWER(dbo.DDB.longitude - (@Lon), 2)) / @Factor
	FROM dbo.DDB WITH (INDEX (NewIndexName))
	WHERE ID = @DDBID

	RETURN COALESCE(@LatLon, 0)

END
GO
-- Then your query looks like this:
DECLARE @Lat FLOAT = 29.935313,
	@Lon FLOAT = -90.068825,
	@Factor FLOAT = 0.014457

SELECT DISTINCT 
    TOP (40) dbo.DDB.brandname, 
	fGetLatLon(@Lat, @Lon, @Factor, dbo.DDB.ID) AS Expr1,
	dbo.DDB.locationName, 
    dbo.DDB.streetLine1, dbo.DDB.city, dbo.DDB.state, dbo.DDB.postalCode, 
    dbo.DDB.brandLogoName, dbo.DDB.locationIdentifier, dbo.DDB.offerIdentifier, 
    dbo.DDB.description, dbo.DDB.categoryIdentifier, dbo.DDB.source
FROM dbo.DDB INNER JOIN
		dbo.CATEGORY_LINKS ON dbo.DDB.categoryIdentifier = dbo.CATEGORY_LINKS.LinkedCategory
WHERE (dbo.DDB.maxprints > dbo.DDB.prints) 
	AND fGetLatLon(@Lat, @Lon, @Factor, dbo.DDB.ID) BETWEEN 0 AND 20

Open in new window

0
Comprehensive Backup Solutions for Microsoft

Acronis protects the complete Microsoft technology stack: Windows Server, Windows PC, laptop and Surface data; Microsoft business applications; Microsoft Hyper-V; Azure VMs; Microsoft Windows Server 2016; Microsoft Exchange 2016 and SQL Server 2016.

 
LVL 48

Accepted Solution

by:
PortletPaul earned 500 total points
ID: 40324615
What happens if you remove DISTINCT and the unused table?
SELECT TOP (40)
      dbo.DDB.brandname
    , SQRT(POWER(dbo.DDB.latitude - 29.935313, 2)
      + POWER(dbo.DDB.longitude - (-90.068825), 2)) / 0.014457 AS Expr1
    , dbo.DDB.locationName
    , dbo.DDB.streetLine1
    , dbo.DDB.city
    , dbo.DDB.state
    , dbo.DDB.postalCode
    , dbo.DDB.brandLogoName
    , dbo.DDB.locationIdentifier
    , dbo.DDB.offerIdentifier
    , dbo.DDB.description
    , dbo.DDB.categoryIdentifier
    , dbo.DDB.source
FROM dbo.DDB
WHERE (dbo.DDB.maxprints > dbo.DDB.prints)
      AND (SQRT(POWER(dbo.DDB.latitude - 29.935313, 2)
      + POWER(dbo.DDB.longitude - (-90.068825), 2)) / 0.014457 BETWEEN 0 AND 20)
ORDER BY
      Expr1

Open in new window

0
 
LVL 45

Expert Comment

by:Vitor Montalvão
ID: 40324769
Use the query to create a view and select from the view:
CREATE VIEW MyViewName
AS
SELECT DISTINCT 
                      TOP (40) dbo.DDB.brandname, SQRT(POWER(dbo.DDB.latitude - 29.935313, 2) 
                      + POWER(dbo.DDB.longitude - (-90.068825), 2)) / 0.014457 AS Expr1, dbo.DDB.locationName, 
                      dbo.DDB.streetLine1, dbo.DDB.city, dbo.DDB.state, dbo.DDB.postalCode, 
                      dbo.DDB.brandLogoName, dbo.DDB.locationIdentifier, dbo.DDB.offerIdentifier, 
                      dbo.DDB.description, dbo.DDB.categoryIdentifier, dbo.DDB.source
FROM         dbo.DDB INNER JOIN
                      dbo.CATEGORY_LINKS ON dbo.DDB.categoryIdentifier = dbo.CATEGORY_LINKS.LinkedCategory
WHERE     (dbo.DDB.maxprints > dbo.DDB.prints) AND (SQRT(POWER(dbo.DDB.latitude - 29.935313, 2) 
                      + POWER(dbo.DDB.longitude - (-90.068825), 2)) / 0.014457 BETWEEN 0 AND 20)
ORDER BY Expr1
GO

SELECT * FROM MyViewName

Open in new window

0
 
LVL 45

Expert Comment

by:Vitor Montalvão
ID: 40324778
If the performance still not good enough then you can try to create the view with SCHEMABINDING.
--Set the options to support indexed views.
SET NUMERIC_ROUNDABORT OFF;
SET ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL, ARITHABORT,
    QUOTED_IDENTIFIER, ANSI_NULLS ON;
GO

CREATE VIEW MyViewName
AS
SELECT DISTINCT 
                      TOP (40) dbo.DDB.brandname, SQRT(POWER(dbo.DDB.latitude - 29.935313, 2) 
                      + POWER(dbo.DDB.longitude - (-90.068825), 2)) / 0.014457 AS Expr1, dbo.DDB.locationName, 
                      dbo.DDB.streetLine1, dbo.DDB.city, dbo.DDB.state, dbo.DDB.postalCode, 
                      dbo.DDB.brandLogoName, dbo.DDB.locationIdentifier, dbo.DDB.offerIdentifier, 
                      dbo.DDB.description, dbo.DDB.categoryIdentifier, dbo.DDB.source
FROM         dbo.DDB INNER JOIN
                      dbo.CATEGORY_LINKS ON dbo.DDB.categoryIdentifier = dbo.CATEGORY_LINKS.LinkedCategory
WHERE     (dbo.DDB.maxprints > dbo.DDB.prints) AND (SQRT(POWER(dbo.DDB.latitude - 29.935313, 2) 
                      + POWER(dbo.DDB.longitude - (-90.068825), 2)) / 0.014457 BETWEEN 0 AND 20)
GO

--Create an index on the view.
CREATE UNIQUE CLUSTERED INDEX MyView_IDX  ON MyViewName (Expr1)
GO

SELECT * FROM MyViewName

Open in new window


Since your view have now a cluster index on Expr1 you shouldn't need the ORDER BY clause.
0
 
LVL 69

Expert Comment

by:ScottPletcher
ID: 40325848
1) Do you have an identity or equivalent unique row column(s) on DDB that is indexed?

2) Can you add an index to DDB if you need to?
0
 
LVL 69

Expert Comment

by:ScottPletcher
ID: 40325876
For example, assume there is an identity column named "id".

Then, first create a covering index for the subquery:

CREATE NONCLUSTERED INDEX DDB__IX_maxprints ON dbo.DDB ( maxprints, prints ) INCLUDE ( id, latitude, longitude )

Then run the main query:

SELECT DISTINCT TOP (40)
                      ddb.brandname, ddb_top_nn.Expr1, ddb.locationName,
                      ddb.streetLine1, ddb.city, ddb.state, ddb.postalCode,
                      ddb.brandLogoName, ddb.locationIdentifier, ddb.offerIdentifier,
                      ddb.description, ddb.categoryIdentifier, ddb.source
FROM (
    SELECT TOP (200)
                          SQRT(POWER(ddb2.latitude - 29.935313, 2) + POWER(ddb2.longitude - (-90.068825), 2)) / 0.014457 AS Expr1,
                          ddb2.id
    FROM         dbo.DDB AS ddb2
    WHERE     (ddb2.maxprints > ddb.prints) AND
              (SQRT(POWER(ddb2.latitude - 29.935313, 2) + POWER(ddb2.longitude - (-90.068825), 2)) / 0.014457 BETWEEN 0.0 AND 20.0)
    ORDER BY         Expr1
) AS ddb_top_nn
INNER JOIN dbo.DDB AS ddb ON ddb.id = ddb_top_nn.id
ORDER BY         ddb_top_nn.Expr1
0
 

Author Closing Comment

by:SimpleDude
ID: 40327677
Paul, that worked perfect. Thanks a lot!

Also, thank you all for the proposed solutions.

Paula
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Load balancing is the method of dividing the total amount of work performed by one computer between two or more computers. Its aim is to get more work done in the same amount of time, ensuring that all the users get served faster.
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
Via a live example, show how to extract insert data into a SQL Server database table using the Import/Export option and Bulk Insert.
Via a live example, show how to setup several different housekeeping processes for a SQL Server.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now