Problem in using STIntersects in SQL Server 2008 - sql-server

Using this Spatial Query I am trying to get all the country information which intersects the point 78,22. Expected result is information of "India", but this query is returning no rows.
select * from countryspatial
where
geom.STIntersects((geometry::STGeomFromText('POINT (78 22)', 4326)))>0;
This is the table definition:
CREATE TABLE [dbo].[CountrySpatial](
[ID] [int] IDENTITY(1,1) NOT NULL,
[ObjectID] [bigint] NULL,
[FIPS_CNTRY] [nvarchar](255) NULL,
[GMI_CNTRY] [nvarchar](255) NULL,
[ISO_2DIGIT] [nvarchar](255) NULL,
[ISO_3DIGIT] [nvarchar](255) NULL,
[ISO_NUM] [int] NULL,
[CNTRY_NAME] [nvarchar](255) NULL,
[LONG_NAME] [nvarchar](255) NULL,
[ISOSHRTNAM] [nvarchar](255) NULL,
[UNSHRTNAM] [nvarchar](255) NULL,
[LOCSHRTNAM] [nvarchar](255) NULL,
[LOCLNGNAM] [nvarchar](255) NULL,
[STATUS] [nvarchar](255) NULL,
[POP2005] [bigint] NULL,
[SQKM] [float] NULL,
[SQMI] [float] NULL,
[COLORMAP] [smallint] NULL,
[geom] [geometry] NULL,
PRIMARY KEY CLUSTERED
(
[ID] 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
ALTER TABLE [dbo].[CountrySpatial] WITH CHECK ADD CONSTRAINT [enforce_srid_geometry_CountrySpatial] CHECK (([geom].[STSrid]=(0)))
GO
ALTER TABLE [dbo].[CountrySpatial] CHECK CONSTRAINT [enforce_srid_geometry_CountrySpatial]
GO

The first thing to comment is that earth surface points should be stored using Geography, not Geometry. There are differences to the storage and how the functions work (even if similarly named)
Here is a working example:
Simplified table:
CREATE TABLE CountrySpatial(
ID int IDENTITY(1,1) NOT NULL PRIMARY KEY,
geog geography NULL)
GO
Insert something that resembles a diamond around India
INSERT INTO CountrySpatial(geog)
VALUES (geography::STGeomFromText('POLYGON((' +
'77.22702 28.67613, ' + -- new delhi (top)
'72.566071 23.059516, ' + -- ahmedabad (left)
'77.593689 13.005227, ' + -- bengaluru (bottom)
'88.374023 22.614011, ' + -- kolkata (right)
'77.22702 28.67613))', 4326));
Find the match. It is UNION-ed to the Point being sought. STBuffer increases the point to a 100km radius, so that it will show up when viewed together with the Geography record found (switch to Spatial tab in the output)
select geog
from countryspatial
where geog.STIntersects(geography::STGeomFromText('POINT (78 22)', 4326))>0
union all
select geography::STGeomFromText('POINT (78 22)', 4326).STBuffer(100000)

Related

Msg 8152 String or binary data would be truncated

I know this has been asked before, but none of the answers are fixing the issue, need another set of eyes. I'm trying to create a table and seed it with some values. I don't have any value constraints so I'm not sure why I'm getting the error I'm getting.
CREATE TABLE [dbo].[AvailableTime]
(
[Id] [INT] IDENTITY(1,1) NOT NULL,
[TimeString] [NCHAR] NOT NULL,
[TimeValue] [NCHAR] NOT NULL,
[CompanyId] [INT] NOT NULL,
[CompanyName] [NVARCHAR](MAX) NULL,
[LocationId] [INT] NOT NULL,
[LocationName] [NVARCHAR] NOT NULL,
[IsClaimed] [BIT] NOT NULL,
CONSTRAINT [PK_AvailableTime]
PRIMARY KEY CLUSTERED ([Id] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
INSERT INTO dbo.AvailableTime (TimeString, TimeValue, CompanyId, CompanyName,
LocationId, LocationName, IsClaimed)
VALUES ('2019-01-07T00:00:00', '12:00 AM', 1, 'Company',
2, 'Inver Grove', 'FALSE');
You should never specify a CHAR, VARCHAR, NCHAR or NVARCHAR column (or variable, or parameter) without specifying an explicit length!
If you omit the specific length, in some cases you'll end up with variable or column of exactly ONE character of length! That's typically NOT what you want!
ALSO: why are you storing TimeString and TimeValue as NCHAR?? Doesn't make any sense - use the most appropriate datatype - and here, that would be DATETIME2(n) and TIME.
So define your table like this:
CREATE TABLE [dbo].[AvailableTime]
(
[Id] [INT] IDENTITY(1,1) NOT NULL,
[TimeString] DATETIM2(0) NOT NULL,
[TimeValue] TIME(0) NOT NULL,
[CompanyId] [INT] NOT NULL,
[CompanyName] [NVARCHAR](MAX) NULL,
[LocationId] [INT] NOT NULL,
[LocationName] [NVARCHAR](100) NOT NULL,
[IsClaimed] [BIT] NOT NULL,
and you should be fine.
You need declare the size of your CHAR & VARCHAR fields in the table:
CREATE TABLE [dbo].[AvailableTime]
(
[Id] [INT] IDENTITY(1,1) NOT NULL,
[TimeString] [NCHAR](50) NOT NULL,
[TimeValue] [NCHAR](50) NOT NULL,
[CompanyId] [INT] NOT NULL,
[CompanyName] [NVARCHAR](MAX) NULL,
[LocationId] [INT] NOT NULL,
[LocationName] [NVARCHAR](50) NOT NULL,
[IsClaimed] [BIT] NOT NULL,
CONSTRAINT [PK_AvailableTime]
PRIMARY KEY CLUSTERED ([Id] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
You have a error in insert query, mismatch types in last column.
INSERT INTO dbo.AvailableTime (TimeString, TimeValue, CompanyId, CompanyName,
LocationId, LocationName, IsClaimed)
VALUES ('2019-01-07T00:00:00', '12:00 AM', 1, 'Company', 2, 'Inver Grove', 0);

Stored procedure not executing the update part until run a second time

I have a stored procedure that, when ran, does an initial insert into a a table from a view, followed by an update statement that modifies a table in the view the first select statement uses (code is below):
ALTER PROCEDURE [dbo].[LFC_sp_LIT_PgmrRequestForm]
AS
BEGIN
SET NOCOUNT ON;
insert into firebird.helpdesk.dbo.tbl_program_request (Requester, Description, Priority, DateRequest, project_status, department, category, requester_email, DueDate, Note)
select dept_name, submitter_first_name + '-' + issue_description, severity_level, getdate(), 'Not Started', dept_name, issue_category, submitter_email, date_due, issue_details
from ics_net..CUS_CF_PGMR_REQUEST_View
where finalbalance = 0;
UPDATE ics_net..CF_Submission
SET finalbalance = 5
WHERE finalbalance = 0
AND FormId = '79A807D9-230B-494C-A609-A284DBBE41B8';
END
This procedure is called whenever a web form is submitted, and the goal is to move the data from the web form database into our help desk database. The web form has a final balance field in the database, that is set to zero. When it is moved, we update it to a non-zero number.
What happens is that the first statement executes, but the second update never happens. Once this is called again, the first statement executes, and the second one works for the statement that was supposed to be previously updated. Things I've tried to resolve the issue are:
Use the ROWLOCK hint for both statements
I've made sure the transaction isolation level is READ COMMITTED
I can't think of anything else to do, other than to use the NOLOCK hint on the select statement, but I'm very hesitant to do that. Any ideas? Thanks.
EDIT 1) Based on some discussion, I want to clarify a couple things:
There aren't any existing triggers on any of the tables
underlying this query.
The initial select is based on a view, while the second update
references a table that makes up the view.
Edit 2) Some more details
The view definition:
ALTER VIEW [dbo].[CUS_CF_PGMR_REQUEST_View] AS
select s.SubmissionId,
s.FormId,
s.SubmittedDate,
s.UserId,
s.Status,
sfn.AnswerValue as [submitter_first_name],
sub_email.AnswerValue as [submitter_email],
dname.AnswerValue as [dept_name],
d_due.AnswerValue as [date_due],
i_cat.AnswerValue as [issue_category],
sec_lev.AnswerValue as [severity_level],
i_desc.AnswerValue as [issue_description],
i_det.AnswerValue as [issue_details],
s.FinalBalance
from CF_Submissions s
left outer join CF_Answers sfn on sfn.ItemID = 'df5307ca-d9a8-4c74-955e-7fe80caafdc0'
and sfn.SubmissionID=s.SubmissionID
left outer join CF_Answers sub_email on sub_email.ItemID = '27e8e2fd-13f8-4c5a-a6bb-bc68fa7d4af5'
and sub_email.SubmissionID=s.SubmissionID
left outer join CF_Answers dname on dname.ItemID = '2826ee1b-759e-4325-b0ba-32a86ed7f07a'
and dname.SubmissionID=s.SubmissionID
left outer join CF_Answers d_due on d_due.ItemID = '5e087866-63ce-41f1-bb32-443770fdf388'
and d_due.SubmissionID=s.SubmissionID
left outer join CF_Answers i_cat on i_cat.ItemID = '32be52b1-1539-4d9b-9f7c-ffb370188396'
and i_cat.SubmissionID=s.SubmissionID
left outer join CF_Answers sec_lev on sec_lev.ItemID = 'f795ff66-342b-4155-86d6-7655dc2b10a5'
and sec_lev.SubmissionID=s.SubmissionID
left outer join CF_Answers i_desc on i_desc.ItemID = '3ff0e614-bdf6-4710-9ba0-6f7356c67032'
and i_desc.SubmissionID=s.SubmissionID
left outer join CF_Answers i_det on i_det.ItemID = 'dd5b797d-a407-4bc7-a73c-daacb3abe660'
and i_det.SubmissionID=s.SubmissionID
where s.FormId = '79a807d9-230b-494c-a609-a284dbbe41b8'
Table Definitions Underlying The View
CREATE TABLE [dbo].[CF_Answers](
[AnswerID] [uniqueidentifier] NOT NULL,
[SubmissionID] [uniqueidentifier] NULL,
[ItemID] [uniqueidentifier] NULL,
[AnswerValue] [varchar](max) NULL,
[MItemID] [uniqueidentifier] NULL,
[RowIndex] [int] NULL,
[ChildItemID] [uniqueidentifier] NULL,
[DisplayText] [varchar](max) NULL,
[NumericValue] [numeric](8, 2) NULL,
[IsVisibleOnSubmit] [bit] NULL,
CONSTRAINT [PK_CF_Answers] PRIMARY KEY CLUSTERED
(
[AnswerID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[CF_Submissions](
[SubmissionID] [uniqueidentifier] NOT NULL,
[UserID] [uniqueidentifier] NULL,
[FormID] [uniqueidentifier] NULL,
[SubmittedDate] [datetime] NULL,
[FinalBalance] [decimal](18, 2) NULL,
[WorkflowID] [uniqueidentifier] NULL,
[Status] [int] NULL,
[TransactionID] [varchar](50) NULL,
[WaiverCode] [varchar](max) NULL,
CONSTRAINT [PK_CF_Submissions] PRIMARY KEY CLUSTERED
(
[SubmissionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
The definition of the destination table for the insert:
CREATE TABLE [dbo].[tbl_program_request](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Requester] [nvarchar](50) NULL,
[Description] [nvarchar](255) NULL,
[Priority] [nvarchar](10) NULL,
[DateRequest] [datetime] NULL,
[WorkingOn] [nvarchar](30) NULL,
[CompletedDate] [datetime] NULL,
[StartDate] [nvarchar](15) NULL,
[Note] [nvarchar](max) NULL,
[project_status] [nvarchar](25) NULL,
[hours_week] [decimal](4, 2) NULL,
[hours_total] [decimal](10, 2) NULL,
[department] [nvarchar](30) NULL,
[category] [nvarchar](20) NULL,
[requester_email] [nvarchar](30) NULL,
[DueDate] [datetime] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
Finally, some sample data that was pulled from the view:
SubmissionId - B81CE5F8-A87B-42B1-9339-2B36166394AB
FormId - 79A807D9-230B-494C-A609-A284DBBE41B8
SubmittedDate - 1/24/2018 16:43
UserId - 58E3958A-A786-4CB9-8EDE-0837ACE187BD
Status - 1
submitter_first_name - SM
submitter_email - email#organization
dept_name - LIT
date_due - 1/28/2018
issue_category -MISC
severity_level - LOW
issue_description - test3
issue_details - test3
FinalBalance - 0
Just to clarify, at the end of the SP, FinalBalance should equal 5. However, it isn't set to 5 until the second time it's ran, causing a double insert into the tbl_program_request table.

SQL Server: extremely slow table on a simple select

I am dealing with a SQL Server on Azure, and I found a rare case where queries over a single table are really slow, over 10 - 12 seconds for a table that has about thousand rows, and while similar tables respond in less that 1 second.
Table definition (script create) is:
CREATE TABLE [dbo].[Content]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[Content_ID] [int] NOT NULL,
[CultureCode] [nvarchar](50) NOT NULL,
[Version] [int] NOT NULL,
[UserID] [int] NOT NULL,
[Timestamp] [datetime] NOT NULL,
[Title] [nvarchar](max) NOT NULL,
[Subtitle] [nvarchar](max) NULL,
... 14 more [nvarchar](max) FIELDS...
[NotesPlainText] [nvarchar](max) NULL,
CONSTRAINT [PK_dbo.Content]
PRIMARY KEY CLUSTERED ([ID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON)
)
(the columns Content_ID, CultureCode and Version seem to be a unique combination, even is not set in the table as that. [ID] is just used as row identifier)
Aside of 17 columns all nvarchar(max), nothing else weird.
As I said, no uniques defined, no index ...
So I tune up as
CREATE TABLE [dbo].[Content_optimized]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[Content_ID] [int] NOT NULL,
[CultureCode] [nvarchar](50) NOT NULL,
[Version] [int] NOT NULL,
[UserID] [int] NOT NULL,
[Timestamp] [datetime] NOT NULL,
[Title] [nvarchar](max) NOT NULL,
[Subtitle] [nvarchar](max) NULL,
... 14 more [nvarchar](max) FIELDS...
[NotesPlainText] [nvarchar](max) NULL,
)
CREATE INDEX IDX_dbo_Content_optimized__Content_ID
ON [dbo].[Content_optimized]([Content_ID])
CREATE INDEX IDX_dbo_Content_optimized__CultureCode
ON [dbo].[Content_optimized]([CultureCode])
CREATE INDEX IDX_dbo_Content_optimized__Version
ON [dbo].[Content_optimized]([Version])
CREATE INDEX IDX_dbo_Content_optimized__UserID
ON [dbo].[Content_optimized]([UserID])
ALTER INDEX ALL ON [dbo].[Content_optimized] REBUILD WITH (FILLFACTOR=90, ONLINE=ON)
and here where things get weird, I am not saving even a single second of execution.
Indeed code like this:
select *
from [Content]
where Content_ID <> 1049
order by Content_ID, Version
select *
from [Content_optimized]
where Content_ID <> 1049
order by Content_ID, Version
gives a 53% and 47% on the execution plan (just 11% faster because of the INDEXes)
Sure I am relative new to SQL optimisation, so there is something I am not seeing here that may be obvious, but I am right now lost on it.
Any help?

Delete Query: 14 minute to no response

I have a Sql Azure database, everything was good from last 6 months until today, when a simple
Delete from ListData where ListID=2323
fail to delete 7500 records out of 1.9 Million records after 14 minutes of running query. However Select query take less than 2-3 second to list them all.
Previously the delete works much like select and it usually take less than 20 second to finish delete operation. something is wrong today only.
Complete database size is 1.1GB where as we have Web edition set at 5GB so, we have plenty of space available.
Any idea what is going wrong? that delete has cause some serious problem in system which cause my client lose quite a money.
Thanks for any guide.
Edit: I do have couple of Index on table, but no trigger, FK or any other such thing in table. LISTID is foreign key [logically], and RecordID [another column in table] is auto increment id in Listdata table.
*Edit 2 *:
/****** Object: Table [dbo].[tblSalesListData] Script Date: 02-07-2013 11:45:14 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[ListData](
[RecordID] [bigint] IDENTITY(1,1) NOT NULL,
[ListID] [bigint] NULL,
[SalesID] [bigint] NULL,
[UserID] [varchar](100) NULL,
[FirstName] [varchar](100) NULL,
[MiddleName] [varchar](50) NULL,
[LastName] [varchar](50) NULL,
[Address1] [varchar](100) NULL,
[Address2] [varchar](100) NULL,
[City] [varchar](100) NULL,
[State] [varchar](100) NULL,
[ZipCode] [varchar](10) NULL,
[WorkPhone] [varchar](15) NULL,
[HomePhone] [varchar](15) NULL,
[CellPhone] [varchar](15) NULL,
[Email] [varchar](100) NULL,
[DealerCode] [varchar](20) NULL,
[IsPrinted] [varchar](10) NULL,
[tag] [varchar](100) NULL,
[RecordDate] [datetime] NULL,
[CustomInfo] [text] NULL,
[SourceData] [text] NULL,
CONSTRAINT [PK_ListData] PRIMARY KEY CLUSTERED
(
[RecordID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[ListData] ADD DEFAULT ('N') FOR [IsPrinted]
GO
Try to add index and change table structure -
CREATE TABLE dbo.tblSalesListData
(
RecordID BIGINT IDENTITY(1,1) NOT NULL PRIMARY KEY,
ListID BIGINT NOT NULL, -- NULL --> NOT NULL
SalesID BIGINT NULL,
UserID VARCHAR(100) NULL,
FirstName VARCHAR(100) NULL,
MiddleName VARCHAR(50) NULL,
LastName VARCHAR(50) NULL,
Address1 VARCHAR(100) NULL,
Address2 VARCHAR(100) NULL,
City VARCHAR(100) NULL,
[State] VARCHAR(100) NULL,
ZipCode VARCHAR(10) NULL,
WorkPhone VARCHAR(15) NULL,
HomePhone VARCHAR(15) NULL,
CellPhone VARCHAR(15) NULL,
Email VARCHAR(100) NULL,
DealerCode VARCHAR(20) NULL,
IsPrinted VARCHAR(10) NULL,
tag VARCHAR(100) NULL,
RecordDate DATETIME NULL,
CustomInfo VARCHAR(MAX) NULL, -- TEXT --> VARCHAR(MAX)
SourceData VARCHAR(MAX) NULL -- TEXT --> VARCHAR(MAX)
)
GO
CREATE /*UNIQUE*/ NONCLUSTERED INDEX IX_ListID ON dbo.tblSalesListData
(
ListID ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
I have a little bit of same problem. I did the following step. but be sure to back up the database before doing these steps.
Create another table with identical structure
Insert the data in new table of the old table
Drop the old table
and try again to see how much time will it take.
Thanks for #Dinup and #Devart that give me idea, though I didn't fully follow their word, but both of them guide me in direction where I found solution as :
Delete all Indexes based on my ListID.
Run my Query, it take less than 1 second now.
Recreate my indexes.
Happy Living.

Why is this join taking so long?

I have the following query that I am running on my database server but it takes about 30 seconds to run and I can't work out why this is.
SELECT *
FROM [dbo].[PackageInstance] AS packInst
INNER JOIN [dbo].[PackageDefinition] AS packageDef
ON packInst.[PackageDefinitionID] = packageDef.[PackageDefinitionID]
LEFT OUTER JOIN [dbo].[PackageInstanceContextDef] AS contextDef
ON packInst.[PackageInstanceID] = contextDef.[PackageInstanceID]
This produced the following execution plan which to me looks to be good....so I can't understand why it takes so much time to execute where the resulting data is only 100,000 records (which should be a walk in the park for SQL Server).
Any ideas what could be causing this long execution time?
I have looked at the query in Profiler to see what the stats where on it and they are as follows:
CPU - 4711
Reads - 744453
Writes - 9
Duration - 26329
The following are the table definitions:
CREATE TABLE [dbo].[PackageDefinition](
[PackageDefinitionID] [int] IDENTITY(1,1) NOT NULL,
[ts] [timestamp] NOT NULL,
[ProgramID] [int] NULL,
[VendorID] [int] NULL,
[PackageExecutionTypeID] [int] NULL,
[PackageDefinitionStatusID] [int] NOT NULL,
[IsInternal] [bit] NOT NULL,
[Name] [dbo].[D_Name] NOT NULL,
[Description] [dbo].[D_Description] NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[PublishedDate] [datetime] NULL,
[OwnerUserGuid] [uniqueidentifier] NOT NULL,
[ProcessDefinitionMainID] [int] NULL,
[KeyInfoHtml] [nvarchar](max) NULL,
[DescriptionHtml] [nvarchar](max) NULL,
[WhatToExpectHtml] [nvarchar](max) NULL,
[BestPracticesHtml] [nvarchar](max) NULL,
[RecommendedJourneysHtml] [nvarchar](max) NULL,
[RequiresSLAAgreement] [bit] NOT NULL,
[SLAFileAssetID] [int] NULL,
[ImageDataID] [int] NULL,
[VideoHtml] [nvarchar](max) NULL,
[VideoAssetID] [int] NULL,
[UseMapCosts] [bit] NOT NULL,
[CostMin] [money] NOT NULL,
[CostMax] [money] NOT NULL,
[LandingPageVisitCount] [int] NOT NULL,
[IsDeleted] [dbo].[D_IsDeleted] NOT NULL,
[CreatedByUserGuid] [uniqueidentifier] NOT NULL,
[OrderHtml] [nvarchar](max) NULL,
CONSTRAINT [PK_PackageDefinition] PRIMARY KEY CLUSTERED
(
[PackageDefinitionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[PackageInstance](
[PackageInstanceID] [int] IDENTITY(1,1) NOT NULL,
[ts] [timestamp] NOT NULL,
[PackageDefinitionID] [int] NOT NULL,
[PackageStatusID] [int] NOT NULL,
[Name] [dbo].[D_Description] NOT NULL,
[CampaignID] [int] NULL,
[MarketingPlanID] [int] NULL,
[CountryID] [int] NULL,
[DateEntered] [datetime] NULL,
[DateExecuted] [datetime] NULL,
[ProcessID] [int] NULL,
[OrderedByUserGuid] [uniqueidentifier] NULL,
[RequestedByUserGuid] [uniqueidentifier] NULL,
[SLAEndDate] [datetime] NULL,
CONSTRAINT [PK_PackageInstance] PRIMARY KEY CLUSTERED
(
[PackageInstanceID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[PackageInstanceContextDef](
[PackageInstanceContextDefID] [int] IDENTITY(1,1) NOT NULL,
[ts] [timestamp] NOT NULL,
[PackageInstanceID] [int] NOT NULL,
[ContextObjectDefID] [int] NOT NULL,
[EnteredFieldValue] [varchar](max) NULL,
[SelectedListValueID] [int] NULL,
[AssetIdsString] [nvarchar](max) NULL,
[SelectedListValueIdsString] [nvarchar](max) NULL,
[ContextObjectFieldName] [nvarchar](30) NOT NULL,
CONSTRAINT [PK_PackageInstanceContextDef] PRIMARY KEY CLUSTERED
(
[PackageInstanceContextDefID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Remove the * in SELECT *
It will always scan because you ask for all columns. And do you have clustered indexes?
The answer turned out to be what #MartinSmith suggested. Because the PackageDefinition table contained about 8 NVARCHAR(MAX) columns, when the resulting join was created and that was over 100k rows, this was causing the varchar(max) values to be re-read over and over and they exist in out of row pages. Hence the large number of logical reads.
Thanks all for your support, just have to figure out to make the entity framework produce the query that I want.
What happens if you add the following index...
CREATE NONCLUSTERED INDEX ix ON PackageDefinition(PackageDefinitionID)
...and try the following to reduce the width of the data going into the sort?
SELECT packInst.*,
packageDef2.*,
contextDef.*
FROM [dbo].[PackageInstance] AS packInst
INNER MERGE JOIN [dbo].[PackageDefinition] AS packageDef
ON packInst.[PackageDefinitionID] = packageDef.[PackageDefinitionID]
LEFT OUTER MERGE JOIN [dbo].[PackageInstanceContextDef] AS contextDef
ON packInst.[PackageInstanceID] = contextDef.[PackageInstanceID]
INNER MERGE JOIN [dbo].[PackageDefinition] AS packageDef2
ON packageDef.[PackageDefinitionID] = packageDef2.[PackageDefinitionID]
OF course * should not be used as even if you need all columns you definitely won't need the same columns twice as the result of the JOIN but this is just to maintain the semantics of your original query.

Resources