SQL query not using created index - sql

I have a table with millions of data and i need to fetch the data with some conditions so I created a non clustered index , but after executing that query it still using the index scan with primary key but not the index I created.
below is the table :
CREATE TABLE [que].[cbsQue](
[requestId] [bigint] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[msg] [nvarchar](max) NULL,
[meta] [nvarchar](max) NULL,
[actionName] [nvarchar](50) NULL,
[recordId] [nvarchar](50) NULL,
[branchId] [nvarchar](20) NULL,
[kmId] [nvarchar](20) NULL,
[queStatus] [nvarchar](20) NULL,
[error] [nvarchar](1000) NULL,
[response] [nvarchar](1000) NULL,
[createdDate] [datetime2](0) NULL,
[updatedDate] [datetime2](0) NULL,
[customerId] [nvarchar](50) NULL)
Below is my query:
SELECT TOP 50 Que.recordId, msg, meta, actionName
FROM que.cbsQue Que
WHERE (queStatus = 'TODO' OR
(queStatus = 'FAILED' AND
(error LIKE 'someString1%'
OR error LIKE '%someString2%'
OR error LIKE '%someString3%'
OR error = 'someString4'
OR error = 'someString5'
OR error = 'someString6'))
)
ORDER BY que.createdDate DESC
Below is the index I created :
CREATE NONCLUSTERED INDEX [CI_queStatus] ON [que].[cbsQue]
(
[queStatus] ASC
)
INCLUDE([error])
how do I use this index to be used in query ?
And is there a way to rewrite the where clause more effectively ?
And the reason for not using the above index might be due to using or in where clause ?

Related

Query not using index in exists statement

I have the index IDX_tbl_SpeedRun_StatusTypeID_GameID_CategoryID_LevelID_PlusInclude on table dbo.tbl_SpeedRun below. The exists statement in the query below is taking a while (1m 10s) saying there is a missing index ON [dbo].[tbl_SpeedRun] ([StatusTypeID],[LevelID]).
Why is the exists statement not using the index I created? It already includes the columns [StatusTypeID],[LevelID].
Table:
CREATE TABLE [dbo].[tbl_SpeedRun]
(
[OrderValue] [int] NOT NULL IDENTITY(1,1),
[ID] [varchar] (50) NOT NULL,
[StatusTypeID] [int] NOT NULL,
[GameID] [varchar] (50) NOT NULL,
[CategoryID] [varchar] (50) NOT NULL,
[LevelID] [varchar] (50) NULL,
[SubCategoryVariableValues] [varchar] (1000) NULL,
[PlayerIDs] [varchar] (1000) NULL,
[PlatformID] [varchar] (50) NULL,
[RegionID] [varchar] (50) NULL,
[IsEmulated] [bit] NOT NULL,
[Rank] [int] NULL,
[PrimaryTime] [bigint] NULL,
[RealTime] [bigint] NULL,
[RealTimeWithoutLoads] [bigint] NULL,
[GameTime] [bigint] NULL,
[Comment] [varchar] (MAX) NULL,
[ExaminerUserID] [varchar] (50) NULL,
[RejectReason] [varchar] (MAX) NULL,
[SpeedRunComUrl] [varchar] (2000) NOT NULL,
[SplitsUrl] [varchar] (2000) NULL,
[RunDate] [datetime] NULL,
[DateSubmitted] [datetime] NULL,
[VerifyDate] [datetime] NULL,
[ImportedDate] [datetime] NOT NULL CONSTRAINT [DF_tbl_SpeedRun_ImportedDate] DEFAULT(GETDATE()),
[ModifiedDate] [datetime] NULL
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[tbl_SpeedRun]
ADD CONSTRAINT [PK_tbl_SpeedRun]
PRIMARY KEY NONCLUSTERED ([ID]) WITH (FILLFACTOR=90) ON [PRIMARY]
GO
CREATE CLUSTERED INDEX [IDX_tbl_SpeedRun_OrderValue]
ON [dbo].[tbl_SpeedRun] ([OrderValue]) WITH (FILLFACTOR=90) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IDX_tbl_SpeedRun_StatusTypeID_GameID_CategoryID_LevelID_PlusInclude]
ON [dbo].[tbl_SpeedRun] ([StatusTypeID], [GameID], [CategoryID],[LevelID])
INCLUDE ([SubCategoryVariableValues], [PlayerIDs], [Rank],[PrimaryTime])
GO
Query:
SELECT
CASE
WHEN EXISTS (SELECT 1 FROM dbo.tbl_SpeedRun rn WITH (NOLOCK)
WHERE rn.LevelID = l.ID AND rn.StatusTypeID = 1)
THEN 1
ELSE 0
END
FROM
dbo.tbl_Level l WITH (NOLOCK)
WHERE
l.GameID = 'pd0wq901'
ORDER BY
l.OrderValue
This is the from clause of your subquery:
WHERE rn.LevelID = l.ID AND rn.StatusTypeID = 1
A helpful index for this predicate would involve the two columns, in any order.
Your existing index does not satisfy that requirement. It has columns:
[StatusTypeID], [GameID], [CategoryID], [LevelID])
INCLUDE ([SubCategoryVariableValues], [PlayerIDs], [Rank], [PrimaryTime])
Both columns are here, but buried within others - so the database cannot take advantage of it to speed up the subquery.
Bottom line: creating a large index that involves a lot of columns does not speed up queries by default. Instead, you can analyze each query individually and define the proper optimization.

SQL Query to update a colums from a table base on a datetime field

I have 2 table called tblSetting and tblPaquets.
I need to update 3 fields of tblPaquets from tblSetting base on a where clause that use a datetime field of tblPaquest and tblSetting.
The sql below is to represent what I am trying to do and I know it make no sense right now.
My Goal is to have One query to achieve this goal.
I need to extract the data from tblSettings like this
SELECT TOP(1) [SupplierID],[MillID],[GradeFamilyID] FROM [tblSettings]
WHERE [DateHeure] <= [tblPaquets].[DateHeure]
ORDER BY [DateHeure] DESC
And Update tblPaquets with this data
UPDATE [tblPaquets]
SET( [SupplierID] = PREVIOUS_SELECT.[SupplierID]
[MillID] = PREVIOUS_SELECT.[MillID]
[GradeFamilly] = PREVIOUS_SELECT.[GradeFamilyID] )
Here the table design
CREATE TABLE [tblSettings](
[ID] [int] NOT NULL,
[SupplierID] [int] NOT NULL,
[MillID] [int] NOT NULL,
[GradeID] [int] NOT NULL,
[TypeID] [int] NOT NULL,
[GradeFamilyID] [int] NOT NULL,
[DateHeure] [datetime] NOT NULL,
[PeakWetEnable] [tinyint] NULL)
CREATE TABLE [tblPaquets](
[ID] [int] IDENTITY(1,1) NOT NULL,
[PaquetID] [int] NOT NULL,
[DateHeure] [datetime] NULL,
[BarreCode] [int] NULL,
[Grade] [tinyint] NULL,
[SupplierID] [int] NULL,
[MillID] [int] NULL,
[AutologSort] [tinyint] NULL,
[GradeFamilly] [int] NULL)
You can do this using CROSS APPLY:
UPDATE p
SET SupplierID = s.SupplierID,
MillID = s.MillID
GradeFamilly = s.GradeFamilyID
FROM tblPaquets p CROSS APPLY
(SELECT TOP (1) s.*
FROM tblSettings s
WHERE s.DateHeure <= p.DateHeure
ORDER BY p.DateHeure DESC
) s;
Notes:
There are no parentheses before SET.
I don't recommend using [ and ] to escape identifiers, unless they need to be escaped.
I presume the query on tblSettings should have an ORDER BY to get the most recent rows.

SQL Server partition and index

I have a requirement to design a table that is going to have around 80 million records. I created a partition for every month using persisted column (if its wrong suggest me the best way). Please find below scripts that I used to create tables and partition and the query that's going to be used often. Only Insertion and deletion will be done on this table.
-- Create the Partition Function
CREATE PARTITION FUNCTION PF_Invoice_item (int)
AS RANGE LEFT FOR VALUES (1,2,3,4,5,6,7,8,9,10,11,12);
-- Create the Partition Scheme
CREATE PARTITION SCHEME PS_Invoice_item
AS PARTITION PF_Invoice_item ALL TO ([Primary]);
CREATE TABLE [Invoice]
(
[invoice_id] [bigint] NOT NULL,
[Invoice_Number] [varchar](255) NULL,
[Invoice_Date] [date] NULL,
[Invoice_Total] [numeric](18, 2) NULL,
[Outstanding_Balance] [decimal](18, 2) NULL,
CONSTRAINT [PK_Invoice_id] PRIMARY KEY CLUSTERED([invoice_id] ASC)
)
CREATE TABLE [InvoiceItem](
[invoice_item_id] [bigint] NOT NULL,
[invoice_id] [bigint] NOT NULL,
[invoice_Date] [date] NULL,
[make] [varchar](255) NULL,
[serial_number] [varchar](255) NULL,
[asset_id] [varchar](100) NULL,
[application] [varchar](255) NULL,
[customer] [varchar](255) NULL,
[ucid] [varchar](255) NULL,
[dcn] [varchar](255) NULL,
[dcn_name] [varchar](255) NULL,
[device_serial_number] [varchar](255) NULL,
[subscription_name] [varchar](255) NULL,
[product_name] [varchar](255) NULL,
[subscription_start_date] [date] NULL,
[subscription_end_date] [date] NULL,
[duration] [varchar](50) NULL,
[promo_name] [varchar](255) NULL,
[promo_end_date] [date] NULL,
[discount] [decimal](18, 2) NULL,
[tax] [decimal](18, 2) NULL,
[line_item_total] [decimal](18, 2) NULL,
[mth] AS (datepart(month,[invoice_date])) PERSISTED NOT NULL,**
[RELATED_PRODUCT_RATEPLAN_NAME] [varchar](250) NULL,
[SUB_TOTAL] [decimal](18, 2) NULL,
[BILLING_START_DATE] [date] NULL,`enter code here`
[BILLING_END_DATE] [date] NULL,
[SUBSCRIPTION_ID] [varchar](200) NULL,
[DEVICE_TYPE] [varchar](200) NULL,
[BASE_OR_PROMO] [varchar](200) NULL,
CONSTRAINT [PK_InvoiceItem_ID] PRIMARY KEY CLUSTERED ([invoice_item_id]
ASC,[mth] ASC))
ON PS_Invoice_item(mth);
GO
ALTER TABLE [InvoiceItem] WITH CHECK ADD CONSTRAINT [FK_Invoice_ID]
FOREIGN KEY([invoice_id])
REFERENCES [Invoice] ([invoice_id])
GO
I will be using below queries
select subscription_name,duration,start_date,end_date,promotion_name,
promotion_end_date,sub_total,discount,tax,line_item_total from InvoiceItem
lt inner join Invoice on lt.invoice_id=invoice.invoice_id where
invoice.invoice_number='' and lt.customer='' and lt.ucid='' lt.make='' and
lt.SERIAL_NUMBER='' and lt.dcn='' and lt.application=''
select customer,make,application from billing.AssetApplicationTotals
lineItem inner join billing.Invoice invoice on
lineItem.invoice_id=invoice.invoice_id where invoice.invoice_number='';
SELECT [invoice_Date],[make],[serial_number],[application],[customer],
[ucid],[dcn],[dcn_name],[device_serial_number]
,[subscription_name],[product_name],[subscription_start_date],
[subscription_end_date],[duration],[promo_name],[promo_end_date]
FROM [InvoiceItem] where [application]=''
SELECT [invoice_Date],[make],[serial_number],[application],[customer],
[ucid],[dcn],[dcn_name],[device_serial_number]
,[subscription_name],[product_name],[subscription_start_date],
[subscription_end_date],[duration],[promo_name],[promo_end_date]
FROM [InvoiceItem] where [customer]=''
What is the best way to create index? Shall I create separate non clustered index for each filter, or shall I have Composite index and shall I have covering index to avoid key lookup?

insert data in fixed length column sql server

I am trying to insert data in fixed length column but I am getting an error.
The table looks like this:
CREATE TABLE [dbo].[zam_pcinfo](
[Id] [decimal] identity NOT NULL,
[employe_name] [nvarchar](50) NOT NULL,
[location_id] [decimal] NOT NULL,
[department_id] [decimal] NOT NULL,
[computer_name] [nvarchar](25) NOT NULL,
[user_name] [nvarchar](25) NOT NULL,
[teamviewer_id] [nvarchar](25) NULL check (DATALENGTH(teamviewer_id) = 9),
[lan_ip] [nvarchar](20) NULL,
[policy] [nvarchar](25) NOT NULL,
[os] [nvarchar](25) NOT NULL,
[pctype] [nvarchar](25) NOT NULL,
[note] [nvarchar](50) NULL,
[password] [nvarchar](25) NOT NULL,
[tmngr] [bit] NOT NULL,
[type_user] [nvarchar] (25) Not null,
[w-internal-mac-address] [nvarchar](50) null)
I am using DATALENGTH function for teamviewer_id column, and when I am trying to insert data into this column it shows this error:
insert statement is conflict with check constraint "nameoftheconstraint" the conflict occurred in database "nameofdatabase", table "nameoftable" column teamviewer_id
Can you help me in that? And is the check constraint is right in this situation?
i use Len instead and its work , thank you

SQL fastest 'GROUP BY' script

Is there any difference in how I edit the GROUP BY command?
my code:
SELECT Number, Id
FROM Table
WHERE(....)
GROUP BY Id, Number
is it faster if i edit it like this:
SELECT Number, Id
FROM Table
WHERE(....)
GROUP BY Number , Id
it's better to use DISTINCT if you don't want to aggregate data. Otherwise, there is no difference between the two queries you provided, it'll produce the same query plan
This examples are equal.
DDL:
CREATE TABLE dbo.[WorkOut]
(
[WorkOutID] [bigint] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[TimeSheetDate] [datetime] NOT NULL,
[DateOut] [datetime] NOT NULL,
[EmployeeID] [int] NOT NULL,
[IsMainWorkPlace] [bit] NOT NULL,
[DepartmentUID] [uniqueidentifier] NOT NULL,
[WorkPlaceUID] [uniqueidentifier] NULL,
[TeamUID] [uniqueidentifier] NULL,
[WorkShiftCD] [nvarchar](10) NULL,
[WorkHours] [real] NULL,
[AbsenceCode] [varchar](25) NULL,
[PaymentType] [char](2) NULL,
[CategoryID] [int] NULL
)
Query:
SELECT wo.WorkOutID, wo.TimeSheetDate
FROM dbo.WorkOut wo
GROUP BY wo.WorkOutID, wo.TimeSheetDate
SELECT DISTINCT wo.WorkOutID, wo.TimeSheetDate
FROM dbo.WorkOut wo
SELECT wo.DateOut, wo.EmployeeID
FROM dbo.WorkOut wo
GROUP BY wo.DateOut, wo.EmployeeID
SELECT DISTINCT wo.DateOut, wo.EmployeeID
FROM dbo.WorkOut wo
Execution plan: