Deadlock from Range locks on primary key index [duplicate] - sql-server-2008

I am getting weird deadlocks on a table (few tables, but they are all similar) and cannot make sense of it no matter how much I try to study Range locks. One process always only SELECT and is taking RangeS-U, then trying to convert it to RangeS-S. Why would Select take RangeS-U in first place? Other process does UPDATE and takes RangeX-X and tries to convert to X. Sometimes second process has X and tries to get X (or I am reading the graph incorrectly). Primary key index fields are never updated and there is no other index on table. The way business process goes, I can be certain that both select and update are working with records with big overlap. Can provide more information if required, table schema and deadlock graph is below.
Table -
CREATE TABLE [dbo].[DeadlockTable] (
[ID] [bigint] NOT NULL ,
[Hour] [tinyint] NOT NULL ,
[Status] [varchar] (32) COLLATE Latin1_General_BIN NOT NULL ,
[MW] [decimal](19, 6) NULL ,
[CreationUserID] [int] NULL ,
[CreationTime] [datetime] NULL ,
[ModificationUserID] [int] NULL ,
[ModificationTime] [datetime] NULL ,
[SubmissionUserID] [int] NULL ,
[SubmissionTime] [datetime] NULL ,
[ConfigurationID] [varchar] (64) COLLATE Latin1_General_BIN NULL ,
CONSTRAINT [PK_DeadlockTable] PRIMARY KEY CLUSTERED
(
[ID],
[Hour]
) ON [PRIMARY]
) ON [PRIMARY]
GO
Deadlock XML -
<deadlock-list>
<deadlock victim="process5e13b88">
<process-list>
<process id="process5e13b88" taskpriority="0" logused="0" waitresource="KEY: 22:72057594344112128 (6123af010c07)" waittime="2978" ownerId="265837907" transactionname="INSERT" lasttranstarted="2017-09-01T10:04:10.767" XDES="0x16fb323b0" lockMode="RangeS-S" schedulerid="2" kpid="5316" status="suspended" spid="83" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2017-09-01T10:04:10.430" lastbatchcompleted="2017-09-01T10:04:09.907" clientapp="..." hostname="..." hostpid="7980" loginname="..." isolationlevel="serializable (4)" xactid="265837907" currentdb="22" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="adhoc" line="40" stmtstart="3776" stmtend="7404" sqlhandle="0x020000009555563118dcb9a28a078c9faa795d95341a9119">
INSERT INTO #TempTable (
...
)
SELECT DISTINCT
...
FROM Table1 B
LEFT JOIN DeadlockTable P ON B.[ID] = {more joins, got cropped}
</frame>
<frame procname="mssqlsystemresource.sys.sp_executesql" line="1" sqlhandle="0x0400ff7fbe80662601000000000000000000000000000000">
sp_executesql
</frame>
<frame procname="EXEC SPROC" line="386" stmtstart="28814" stmtend="29462" sqlhandle="0x03001600afff210aad8d3f01d0a700000100000000000000">
EXEC sp_executesql ...
</frame>
<frame procname="adhoc" line="1" sqlhandle="0x010016009a0b8926e0fb577e010000000000000000000000">
EXEC SPROC ...
</frame>
</executionStack>
<inputbuf>
EXEC SPROC ...
</inputbuf>
</process>
<process id="process5e45b88" taskpriority="0" logused="236" waitresource="KEY: 22:72057594344112128 (55ed2fdeaf5a)" waittime="3130" ownerId="265839001" transactionname="UPDATE" lasttranstarted="2017-09-01T10:04:14.840" XDES="0x484c171b0" lockMode="X" schedulerid="7" kpid="4852" status="suspended" spid="90" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2017-09-01T10:04:14.817" lastbatchcompleted="2017-09-01T10:04:11.883" clientapp="..." hostname="..." hostpid="7980" loginname="..." isolationlevel="read committed (2)" xactid="265839001" currentdb="22" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="EXEC SPROC2" line="141" stmtstart="9324" stmtend="10424" sqlhandle="0x03001600a8150d4e1c673f01d0a700000100000000000000">
UPDATE BP
SET BP.[Status] = CASE #Cancel WHEN 1 THEN &apos;Voided&apos; ELSE &apos;Submitted&apos; END, BP.[MW] = CASE #Cancel WHEN 1 THEN 0 ELSE BP.[MW] END, BP.[SubmissionUserID] = #SubmissionUserID, BP.[SubmissionTime] = #SubmissionTime
FROM #FinalResult FR
CROSS JOIN Hour25 H25
INNER JOIN DeadLockTable BP ON BP.[ID] = FR.[ID] AND BP.[Hour] = H25.[HE]
INNER JOIN fnc_List2Table(#HourList, &apos;,&apos;) HL ON H25.[HE] = HL.[Value] OR #HourList = &apos;0&apos;
WHERE (FR.[MarketType] = 1 OR (FR.[MarketType] = 2 AND BP.[Hour] = FR.[Hour]))
</frame>
<frame procname="adhoc" line="2" stmtstart="18" sqlhandle="0x010016002c9cbb0aa05380f3000000000000000000000000">
EXEC SPROC2
</frame>
</executionStack>
<inputbuf>
EXEC SPROC2
</inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594344112128" dbid="22" objectname="DealockTable" indexname="PK_DealockTable" id="lock451ea9e80" mode="X" associatedObjectId="72057594344112128">
<owner-list>
<owner id="process5e45b88" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process5e13b88" mode="RangeS-S" requestType="wait"/>
</waiter-list>
</keylock>
<keylock hobtid="72057594344112128" dbid="22" objectname="DealockTable" indexname="PK_DealockTable" id="lock109ed6380" mode="RangeS-U" associatedObjectId="72057594344112128">
<owner-list>
<owner id="process5e13b88" mode="RangeS-S"/>
</owner-list>
<waiter-list>
<waiter id="process5e45b88" mode="X" requestType="convert"/>
</waiter-list>
</keylock>
</resource-list>
</deadlock>
</deadlock-list>
Deadlock Graph

It's classic deadlock when one process(victim) reads on serializable level and another updates the same clustered table.
You are confused with what is converted to what.
The first process ("process5e13b88") has acquired RangeS-S lock and waits for another RangS-S lock (where there is X lock of update process), it converts nothing.
The second "process5e45b88" has acquired X lock on one key and U on another key and wants to convert it to X but it cannot because there is RangeS-S lock.
I attach the picture where you can see that one process wants and acquires only RangeS-S locks and another only X locks.
When you see RangeS-U lock this means there is RangeS-S lock on the range but the key itself has U lock

Try creating a nonclustered index on your deadlock table using the join columns as key columns and the returned (i.e. columns in the SELECT section) columns as included columns.
Read Using a Clustered Index to Solve a SQL Server Deadlock Issue for further explanation. I know the title doesn't sound like what I'm telling you to do, but the article shows how a nonclustered index can be used to resolve deadlock issues.

Related

SQL Merge Statement Check Constraint Error

I have the following code table A has a check constraint on column Denial.
CREATE TABLE Table a
(
[ID] int IDENTITY(1,1) NOT NULL ,
[EntityID] int ,
Denial nVarchar(20)
CONSTRAINT Chk_Denial CHECK (Denial IN ('Y', 'N')),
)
Merge statement
MERGE INTO Table a WITH (HOLDLOCK) AS tgt
USING (SELECT DISTINCT
JSON_VALUE(DocumentJSON, '$.EntityID') AS EntityID,
JSON_VALUE(DocumentJSON, '$.Denial') AS Denial
FROM Table1 bd
INNER JOIN table2 bf ON bf.FileUID = bd.FileUID
WHERE bf.Type = 'Payment') AS src ON tgt.[ID] = src.[ID]
WHEN MATCHED
)) THEN
UPDATE SET tgt.ID = src.ID,
tgt.EntityID = src.EntityID,
tgt.Denial = src.Denial,
WHEN NOT MATCHED BY TARGET
THEN INSERT (ID, EntityID, Denial)
VALUES (src.ID, src.EntityID, src.Denial)
THEN DELETE
I get this error when running my MERGE statement:
Error Message Msg 547, Level 16, State 0, Procedure storproctest1, Line 40 [Batch Start Line 0]
The MERGE statement conflicted with the CHECK constraint "Chk_Column". The conflict occurred in the database "Test", table "Table1", and column 'Denial'. The statement has been terminated.
This is due to the source files having "Yes" and "No" instead of 'Y' and 'N'. Hence, I'm getting the above error.
How can I use a Case statement in merge statement to handle the above Check constraints error? or Any alternative solutions.
You can turn Yes to Y and No to N before merging your data. That would belong to the using clause of the merge query:
USING (
SELECT Distinct
JSON_VALUE(DocumentJSON, '$.EntityID') AS EntityID,
CASE JSON_VALUE(DocumentJSON, '$.Denial')
WHEN 'Yes' THEN 'Y'
WHEN 'No' THEN 'N'
ELSE JSON_VALUE(DocumentJSON, '$.Denial')
END AS Denial
FROM Table1 bd
INNER JOIN table2 bf ON bf.FileUID = bd.FileUID
WHERE bf.Type = 'Payment'
) AS src
The case expression translates Y and N values, and leaves other values untouched. Since this applies to the source dataset, the whole rest of the query benefits (ie both the update and insert branches).

How to MySQL REPLACE html/mjml code with html tags

I have a lot of email templates stored in MySQL database.
Inside i have a table which stores the MJML code of the template.
Now I want to update a few lines of code in all of my emails. And I want to do it inside MySQL because it would be fast. (hundreds of emails)
The table "mymjmltemplates" has three columns:
id int(10), email_id int(10), custom_mjml (longtext)
My query goes like this:
UPDATE mymjmltemplates
SET custom_mjml = REPLACE(
custom_mjml,
'<mj-column>
<mj-text>Content 1
</mj-text>
</mj-column>',
'<mj-column>
<mj-text>Content 2
</mj-text>
</mj-column>')
WHERE email_id = 1035;
Usually this query updates strings. But when I run it, it breaks somewhere and asks during the query:
Display all 2709 possibilities? (y or n)
Without entering something it finishes the query, and changes nothing.
So, it is escaping somehow inside the strings??? I don't find a connection.
This is how it looks like on my cli:
MariaDB [mydatabase]> UPDATE mymjmltemplates
-> SET custom_mjml = REPLACE(custom_mjml,
->
Display all 2709 possibilities? (y or n)
-> >
->
Display all 2709 possibilities? (y or n)
-> tent 1
->
Display all 2709 possibilities? (y or n)
? categories.description leads.state
ABS categories.id leads.storecode
ACOS categories.is_published leads.timezone
ACTION categories.modified_by leads.title
ADD categories.modified_by_user leads.treueaktion_gutschein_ein
ADDDATE categories.title leads.twitter
ADDTIME category_id leads.warenkorbwert_abbruch
AES_DECRYPT channel leads.website
AES_ENCRYPT channel_id leads.weitere_informationen
AFTER channel_url_trackables leads.zahlungsart
AGAINST channel_url_trackables.channel leads.zipcode
AGGREGATE channel_url_trackables.channel_id line_count
ALGORITHM channel_url_trackables.hits linkedin
ALL channel_url_trackables.redirect_id list_id
ALTER channel_url_trackables.unique_hits lists
ANALYZE charset load data from
AND checked_out locale
ANY checked_out_by lock tables
AREA checked_out_by_user log_counts_processed
AS city log_id
ASBINARY clear manually_added
ASC click_count manually_removed
ASCII click_details markenbotschafter
ASENSITIVE client_id mautic
ASIN client_info max_attempts
ASTEXT code media_id
ASWKB color media_path
ASWKT column_is_not_created merged_id
ATAN column_name message
ATAN2 column_type message_channels
AUTO_INCREMENT column_value message_channels.channel
AVG columns message_channels.channel_id
AVG_ROW_LENGTH comments message_channels.id
BACKUP companies message_channels.is_enabled
BDB companies.checked_out message_channels.message_id
BEFORE companies.checked_out_by message_channels.properties
BEGIN companies.checked_out_by_user message_id
BENCHMARK companies.companyaddress1 message_queue
BERKELEYDB companies.companyaddress2 message_queue.attempts
BETWEEN companies.companyannual_revenue message_queue.channel
BIGINT companies.companycity message_queue.channel_id
BIN companies.companycountry message_queue.date_published
BINARY companies.companydescription message_queue.date_sent
BINLOG companies.companyemail message_queue.event_id
BIT companies.companyfax message_queue.id
BIT_AND companies.companyindustry message_queue.last_attempt
BIT_COUNT companies.companyname message_queue.lead_id
BIT_LENGTH companies.companynumber_of_employees message_queue.max_attempts
BIT_OR companies.companyphone message_queue.options
BIT_XOR companies.companystate message_queue.priority
BLOB companies.companywebsite message_queue.scheduled_date
BOOL companies.companyzipcode message_queue.status
BOOLEAN companies.created_by message_queue.success
BOTH companies.created_by_user messages
BTREE companies.date_added messages.category_id
BY companies.date_modified messages.checked_out
BYTE companies.id messages.checked_out_by
CACHE companies.is_published messages.checked_out_by_user
CALL companies.modified_by messages.created_by
CASCADE companies.modified_by_user messages.created_by_user
CASCADED companies.owner_id messages.date_added
CASE companies.score messages.date_modified
CAST companies.social_cache messages.description
CEIL companies_leads messages.id
CEILING companies_leads.company_id messages.is_published
CENTROID companies_leads.date_added messages.modified_by
CHAIN companies_leads.is_primary messages.modified_by_user
CHANGE companies_leads.lead_id messages.name
CHANGED company messages.publish_down
CHAR company_id messages.publish_up
CHARACTER companyaddress1 meta_description
CHARACTER_LENGTH companyaddress2 metadata
CHARSET companyannual_revenue migrations
CHAR_LENGTH companycity migrations.executed_at
CHECK companycountry migrations.version
CHECKSUM companydescription mime
CIPHER companyemail mobile
CLIENT companyfax mobileSettings
CLOSE companyindustry modified_at
COALESCE companyname modified_by
CODE companynumber_of_employees modified_by_user
COERCIBILITY companyphone monitor_id
COLLATE companystate monitor_post_count
COLLATION companywebsite monitor_post_count.id
COLUMN companyzipcode monitor_post_count.monitor_id
COLUMNS conditions monitor_post_count.post_count
COMMENT connect monitor_post_count.post_date
COMMIT contact_id monitoring
COMMITTED contact_merge_records monitoring.category_id
COMPACT contact_merge_records.contact_id monitoring.checked_out
COMPRESS contact_merge_records.date_added monitoring.checked_out_by
COMPRESSED contact_merge_records.id monitoring.checked_out_by_user
CONCAT contact_merge_records.merged_id monitoring.created_by
CONCAT_WS contact_merge_records.name monitoring.created_by_user
CONCURRENT container_attr monitoring.date_added
CONDITION content monitoring.date_modified
CONNECTION copy_id monitoring.description
CONNECTION_ID country monitoring.id
-> >',
'>
Display all 2709 possibilities? (y or n)
'> >
'>
Display all 2709 possibilities? (y or n)
'> tent 2
'>
Display all 2709 possibilities? (y or n)
? categories.description leads.state
ABS categories.id leads.storecode
ACOS categories.is_published leads.timezone
ACTION categories.modified_by leads.title
ADD categories.modified_by_user leads.treueaktion_gutschein_ein
ADDDATE categories.title leads.twitter
ADDTIME category_id leads.warenkorbwert_abbruch
AES_DECRYPT channel leads.website
AES_ENCRYPT channel_id leads.weitere_informationen
AFTER channel_url_trackables leads.zahlungsart
AGAINST channel_url_trackables.channel leads.zipcode
AGGREGATE channel_url_trackables.channel_id line_count
ALGORITHM channel_url_trackables.hits linkedin
ALL channel_url_trackables.redirect_id list_id
ALTER channel_url_trackables.unique_hits lists
ANALYZE charset load data from
AND checked_out locale
ANY checked_out_by lock tables
AREA checked_out_by_user log_counts_processed
AS city log_id
ASBINARY clear manually_added
ASC click_count manually_removed
ASCII click_details markenbotschafter
ASENSITIVE client_id mautic
ASIN client_info max_attempts
ASTEXT code media_id
ASWKB color media_path
ASWKT column_is_not_created merged_id
ATAN column_name message
ATAN2 column_type message_channels
AUTO_INCREMENT column_value message_channels.channel
AVG columns message_channels.channel_id
AVG_ROW_LENGTH comments message_channels.id
BACKUP companies message_channels.is_enabled
BDB companies.checked_out message_channels.message_id
BEFORE companies.checked_out_by message_channels.properties
BEGIN companies.checked_out_by_user message_id
BENCHMARK companies.companyaddress1 message_queue
BERKELEYDB companies.companyaddress2 message_queue.attempts
BETWEEN companies.companyannual_revenue message_queue.channel
BIGINT companies.companycity message_queue.channel_id
BIN companies.companycountry message_queue.date_published
BINARY companies.companydescription message_queue.date_sent
BINLOG companies.companyemail message_queue.event_id
BIT companies.companyfax message_queue.id
BIT_AND companies.companyindustry message_queue.last_attempt
BIT_COUNT companies.companyname message_queue.lead_id
BIT_LENGTH companies.companynumber_of_employees message_queue.max_attempts
BIT_OR companies.companyphone message_queue.options
BIT_XOR companies.companystate message_queue.priority
BLOB companies.companywebsite message_queue.scheduled_date
BOOL companies.companyzipcode message_queue.status
BOOLEAN companies.created_by message_queue.success
BOTH companies.created_by_user messages
BTREE companies.date_added messages.category_id
BY companies.date_modified messages.checked_out
BYTE companies.id messages.checked_out_by
CACHE companies.is_published messages.checked_out_by_user
CALL companies.modified_by messages.created_by
CASCADE companies.modified_by_user messages.created_by_user
CASCADED companies.owner_id messages.date_added
CASE companies.score messages.date_modified
CAST companies.social_cache messages.description
CEIL companies_leads messages.id
CEILING companies_leads.company_id messages.is_published
CENTROID companies_leads.date_added messages.modified_by
CHAIN companies_leads.is_primary messages.modified_by_user
CHANGE companies_leads.lead_id messages.name
CHANGED company messages.publish_down
CHAR company_id messages.publish_up
CHARACTER companyaddress1 meta_description
CHARACTER_LENGTH companyaddress2 metadata
CHARSET companyannual_revenue migrations
CHAR_LENGTH companycity migrations.executed_at
CHECK companycountry migrations.version
CHECKSUM companydescription mime
CIPHER companyemail mobile
CLIENT companyfax mobileSettings
CLOSE companyindustry modified_at
COALESCE companyname modified_by
CODE companynumber_of_employees modified_by_user
COERCIBILITY companyphone monitor_id
COLLATE companystate monitor_post_count
COLLATION companywebsite monitor_post_count.id
COLUMN companyzipcode monitor_post_count.monitor_id
COLUMNS conditions monitor_post_count.post_count
COMMENT connect monitor_post_count.post_date
COMMIT contact_id monitoring
COMMITTED contact_merge_records monitoring.category_id
COMPACT contact_merge_records.contact_id monitoring.checked_out
COMPRESS contact_merge_records.date_added monitoring.checked_out_by
COMPRESSED contact_merge_records.id monitoring.checked_out_by_user
CONCAT contact_merge_records.merged_id monitoring.created_by
CONCAT_WS contact_merge_records.name monitoring.created_by_user
CONCURRENT container_attr monitoring.date_added
CONDITION content monitoring.date_modified
CONNECTION copy_id monitoring.description
CONNECTION_ID country monitoring.id
'> >')
-> WHERE email_id = 1035;
To me, it looks like some combinations of characters lead to escaping and then some weird things happen.
What am I doing wrong? Why is this happening?
I appreciate every help/idea

Report the line manager of your line manager where they have a Manager flag (loops)

CREATE TABLE `empTest` (
`keysearch` INT(8) NOT NULL,
`flg_manager` INT(1) NOT NULL,
`fk_manager` INT(8) NOT NULL,
PRIMARY KEY (`keysearch`)
)
INSERT INTO `empTest` (`keysearch`, `fk_manager`, `flg_manager`) VALUES ('5407', '5866', 0);
INSERT INTO `empTest` (`keysearch`, `fk_manager`, `flg_manager`) VALUES ('5866', '0679', 0);
INSERT INTO `empTest` (`keysearch`, `fk_manager`, `flg_manager`) VALUES ('0679', '9177', 1);
INSERT INTO `empTest` (`keysearch`, `fk_manager`, `flg_manager`) VALUES ('9177', '0011', 1);
In the example data above there are 3 users (4th being the last line manager). I would like to be able to select the "1st keysearch where they have the flg_manager set as 1" as AuthManager (indicating they are an Authorising manager)
The query result I am looking to achieve is:
Keysearch,AuthManager
5407,0679
5866,0679
0679,9177
I am thinking it needs to be a loop but I really don't know where to start. I understand I need to use the middle employee as a Join to be able to see from employee 5407 to employee 0679. Annoyingly in this example there is only one employee to 'jump' but I need to be able to account for up to 8 jumps.
Completely Wrong - but I'm at a complete loss...
SELECT e.keysearch, #manager AS manager
FROM emptest e, emptest m1, emptest m2
WHERE #manager = CASE WHEN (
SELECT e.fk_manager
FROM e
WHERE e.fk_manager = m1.keysearch AND m1.flg_manager = 1)
Else When...
Will I need to do lots of Case loops?
Any Suggestions? Running MariaDB 10.3.

MySQL Slow query with multiple joins and subqueries

I have 3 tables:
Pi - images
Pidl - images dl log => Pidl
Pirl - images resize log => Pidl
Basically an image is downloaded and a log record is created in Pidl. After that, it's resized and a record is created in Pirl. Said record being connected to the Pidl record.
I am writing a query as to find which images need to be resized and it basically queries Pidl. The algo I've devised is simple:
for each Image in Pi {
pidlA=newest_pidl(Image);
if(pidlA.status == success) {
pirlA=newest_pirl(Image);
if(pirlA.pidl.hash != pidlA.hash)
{
go;
}
else if(pirlA.status != success){
failed_attempts = failed_pirl_count(pirlA,newest_succesful_pirl(Image))
decide based on pirlA.time and failed_attempts if go or not
}
else
{
dont go;
}
}
else
{
dont go;
}
}
And now my query(altough is not yet finished, the failed attempts part is missing, but it's already too slow, so first I'd like to fix that).
SELECT
pidl1A.pidl_id
FROM Pidl as pidl1A
LEFT JOIN Pidl as pidl2A
ON (
pidl1A.pidl_pi_id = pidl2A.pidl_pi_id AND
pidl2A.pidl_status = 1 AND
(pidl2A.pidl_time > pidl1A.pidl_time OR
(pidl2A.pidl_id > pidl1A.pidl_id and pidl1A.pidl_time=pidl2A.pidl_time)
)
)
LEFT JOIN (
#newest pirl subquery#
SELECT
pidl1B.pidl_pi_id as sub_pi_id,
pidl1B.pidl_hash as sub_pidl_hash,
pirl1B.pirl_id as sub_pirl_id,
pirl1B.pirl_status as sub_pirl_status
FROM Pirl as pirl1B
INNER JOIN Pidl as pidl1B ON (pirl1B.pirl_pidl_id = pidl1B.pidl_id)
LEFT JOIN (
SELECT
pidl2B.pidl_pi_id as sub_pi_id,
pirl2B.pirl_id as sub_pirl_id,
pirl2B.pirl_time as sub_pirl_time
FROM Pirl as pirl2B
INNER JOIN Pidl as pidl2B ON (pirl2B.pirl_pidl_id = pidl2B.pidl_id)
WHERE 1
) as pirl3B
ON (
pirl3B.sub_pi_id = pidl1B.pidl_pi_id and
(pirl3B.sub_pirl_time > pirl1B.pirl_time or
(pirl3B.sub_pirl_time = pirl1B.pirl_time and
pirl3B.sub_pirl_id > pirl1B.pirl_id)
)
)
WHERE
pirl3B.sub_pirl_id is null
) as pirl1A
ON (pirl1A.sub_pi_id = pidl1A.pidl_pi_id)
WHERE
pidl1A.pidl_status = 1 AND pidl2A.pidl_id IS NULL
AND (
pirl1A.sub_pirl_id IS NULL
OR (
pidl1A.pidl_hash != pirl1A.sub_pidl_hash
)
OR (
pirl1A.sub_pirl_status != 1
)
)
And this is my db schema:
CREATE TABLE Pi (
`pi_id` int,
PRIMARY KEY (`pi_id`)
)
;
CREATE TABLE Pidl
(
`pidl_id` int,
`pidl_pi_id` int,
`pidl_status` int,
`pidl_time` int,
`pidl_hash` varchar(16),
PRIMARY KEY (`pidl_id`)
)
;
alter table Pidl
add constraint fk1_branchNo foreign key (pidl_pi_id) references Pi (pi_id);
CREATE TABLE Pirl
(
`pirl_id` int,
`pirl_pidl_id` int,
`pirl_status` int,
`pirl_time` int,
PRIMARY KEY (`pirl_id`)
)
;
alter table Pirl
add constraint fk2_branchNo foreign key (pirl_pidl_id) references Pidl (pidl_id);
INSERT INTO Pi
(`pi_id`)
VALUES
(3),
(4),
(5);
INSERT INTO Pidl
(`pidl_id`, `pidl_pi_id`,`pidl_status`,`pidl_time`, `pidl_hash`)
VALUES
(1, 3, 1,100, 'hashA'),
(2, 3, 1,150,'hashB'),
(3, 4, 2, 200,'hashC'),
(4, 3, 1, 200,'hashA')
;
INSERT INTO Pirl
(`pirl_id`, `pirl_pidl_id`,`pirl_status`,`pirl_time`)
VALUES
(1, 2, 0,100),
(2, 3, 1,150),
(3, 1, 2, 200)
;
Of course with 3 records it's fast. But with around 10-30k it takes more than 5 seconds. What I've found is that the thing that makes it slow is the last part of the where:
AND (
pirl1A.sub_pirl_id IS NULL
OR (
pidl1A.pidl_hash != pirl1A.sub_pidl_hash
)
OR (
pirl1A.sub_pirl_status != 1
)
)
The other strange thing that I've found is that by using DISTINCT, the query got a bit faster but not fast enough.
When I read your requirements, I come up with a query like this:
select pidl.*
from pidl left join
(select image, max(pidl_time) as pidl_time
from pidl
group by image
) maxpidl
on pidl.image = maxpidl.image and pidl.pidl_time = maxpidl.pidl_time
pirl
on pidl.hash = pirl.hash
where pirl.hash is null;
I think you have some other conditions that are not fully explained (such as the role of status). You should be able to incorporate that.
In MySQL, you should avoid subqueries in the from clause. These are materialized and -- as a result -- there is additional overhead for that work and the engine cannot subsequently use indexes.
Your queries aren't using your indexes, and are instead using views in a subquery. This can be very slow. I would suggest making new tables that are indexed with the information that you need or a materialized view.

Is there a way to alter (drop/create) a user defined table type without deleting dependents

Is there a way to alter (drop and create) user defined Table type without dropping dependent object.
I have this table type
CREATE TYPE [dbo].[ttOrderItems] AS TABLE(
[Position] [int] NULL,
[ItemCode] [varchar](16) NULL,
[QtyOrdered] [int] NULL,
[UOM] [varchar](2) NULL,
[PriceQuoted] [decimal](10, 2) NULL
)
and dependent table type function
CREATE function [dbo].[ftCatalogItems](#comno varchar(3),#cuno varchar(6),#items ttOrderItems readonly) returns table as
/*-------------------------------------------------------
DECLARE #COMNO VARCHAR(3)='010',#CUNO VARCHAR(6)='000164'
declare #items ttOrderItems;
select * from #items
insert #items
select '1231-221',1,'EA',20.20
union select '110223-245',10,'EA',2001.20
--------------------------------------------------------*/
return(
select Position,ItemCode,QtyOrdered
,PriceQuoted
,Net
,t$qanp QtyApplicable
,Status=case
when t$item is null then 'Not in Catalog'
when t$stdt > getdate() then 'Availle only on or after '+Convert(varchar(30),t$stdt,106)
when datediff(DD,getdate(),isnull(nullif(t$tdat,''),'4712-01-01')) < 1 then 'EXPIRED'
when items.PriceQuoted != Net then 'Quoted Price do not match Catalog price'
else Null
end
from #items items
Left Join ediCatalog c on ltrim(c.t$item)=ItemCode AND COMNO=#COMNO AND T$CUNO=#CUNO and c.[Server]=dbo.fsBaanServer()
)
Now I want to alter (drop/create) the type ttOrderItems,. How can I do this without first dropping the ftCatalogItems ?
As per my knowledge it's not possible.
http://msdn.microsoft.com/en-IN/library/ms174407.aspx
To Alter table name
sp_rename old_table_name, new_table_name
You could temporary delete the dependencies and then re-create them. You could automate this process, see my answer here.