en-USsv-SE

Active Forums

PrevPrev Go to previous topic
NextNext Go to next topic
Last Post 05 Jan 2016 04:26 PM by  JAhlen
SQLug.se Challenge 2015
 48 Replies
Sort:
You are not authorized to post a reply.
Page 3 of 3 << < 123
Author Messages
Karfunkel
New Member
New Member
Posts: 11


--
11 Dec 2015 11:26 AM
Grattis Sergey!
Du säger i din beskrivning att "andra steget måste ske seriellt". Det stämmer inte, och jag gjorde en procedur som skulle köra just det steget parallellt, men hann inte komma i mål med Message Broker.

Problemet i steg två är att om man börjar räkna på olika kort, så kommer man att få olika resultat. Det är däremot ett marginellt problem, eftersom det räcker att två procedurer kommer fram till någon "stoppstatus" (S/L/W/B) för samma kort, så är de i synk därefter. När jag testade detta tog det i storleksordningen 20 kort för processerna att komma i synk.

Min idé var därför att låta de olika processerna börja arbeta i olika delar av tabellen, med jämna mellanrum. Låt säga att process 1 börjar på kort 1 och process 2 på kort 100.001. När process 1 når fram till kort 100.001, så fortsätter den att jobba och skriva över det process 2 har skrivit, ända tills den skriver över en stoppstatus med en stoppstatus. Då lägger den av.

Jag skulle gärna se hela listan på de 15 bidrag som godkändes.

/Torbjörn
Mikael Eriksson
New Member
New Member
Posts: 12


--
11 Dec 2015 04:32 PM
Även jag har använt liknande sätt som vinnaren denna gång.

Ladda inmem-tabell parallellt med Service Broker.
Nativley compiled stored procedure för att beräkna status.
Parallel SB för att uppdatera status.

Jag använd också 16 (ev 17) partitioner dock multipla queue readers istället för multipla köer.
En väsentlig skillnad är att jag inte optimerade för att hantera en hel page i en tråd och jag använde inte pagelock.

Grattis Sergey, väl förtjänt.

Setup:
http://pastebin.com/cxaKvM2A

Main:
http://pastebin.com/6w92XVWT

/Mikael Eriksson
Sergey
New Member
New Member
Posts: 16


--
11 Dec 2015 04:46 PM
Tackar och bockar ödmjukt för alla gratulationer.

Det var roligt att se Stefans lösnig som har samma ide även i små detaljer men lite annorlunda implementation. En sak jag noterat är att vid inläsning till @Input används inte PAGLOCK – jag fick bättre stabilitet med det.

Daniels lösning med att operera på färre rader är oväntat effektiv trots all hantering av strängar. Så den kommer jag att ta med mig lika som trace flag 8649 för CROSS APPLY – riktigt fyndigt.

Torbjörn, jag hann inte förstå din teori för parallell körning av andra steget än. Kan du posta en körbar demo på din teori?

//Sergey
Karfunkel
New Member
New Member
Posts: 11


--
11 Dec 2015 05:04 PM
Tanken var att använda följande tabell och procedur. Proceduren tar en tinyint som parameter, vilken är processens nummer. Process nr 1 börjar på kort nr 1, process 2 börjar på kort nr 1+[tabellens längd]/8, o.s.v.

Jag har testat proceduren, så det är inte "teori". Det går lätt att verifiera genom att köra procedurer med högst nummer först, för att illustrera vad som händer "i överlappet".


CREATE TABLE dbo.CardTable(
CardID int NOT NULL PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 2000000),
Rank tinyint,
Status char(1),
Process tinyint,
Locked bit
)
WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_ONLY);
GO

CREATE PROCEDURE [dbo].[sp_ComputeStatusParallel]
@process tinyint
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER
AS
BEGIN ATOMIC
WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english', DELAYED_DURABILITY = ON)
DECLARE @lowVal tinyint = 0;
DECLARE @highVal tinyint = 0;
DECLARE @Scount int = 0;
DECLARE @Lcount int = 0;
DECLARE @Wcount int = 0;
DECLARE @Bcount int = 0;
DECLARE @iterator int;
DECLARE @card tinyint;
DECLARE @numCards int = 0;
DECLARE @status char;
DECLARE @prevproc tinyint;
DECLARE @slwb bit;
DECLARE @locked bit = 0;
DECLARE @numRows int;
DECLARE @startat int;

SELECT @numRows = MAX(CardID)
FROM dbo.CardTable;

SET @startat = 1+(@process-1)*@numRows/8;
SET @iterator = @startat;

WHILE @iterator <= @numRows
BEGIN
SET @slwb = 0;
SET @status = NULL;
SELECT
@card = [Rank],
@status = [Status],
@prevproc = [Process],
@locked = [Locked]
FROM dbo.CardTable
WHERE CardID = @iterator;
IF (@locked = 0 AND @prevproc > @process)
BEGIN
UPDATE dbo.CardTable
SET Locked = 1
WHERE CardID = @iterator;
SET @numCards += 1;
IF (@card = 1) --Ess
BEGIN
SET @lowVal += 1;
SET @highVal += 11;
END
ELSE
IF (@card > 9) --10, Kn, D, K
BEGIN
SET @lowVal += 10;
SET @highVal += 10;
END
ELSE
BEGIN --Övriga
SET @lowVal += @card;
SET @highVal += @card;
END
IF (@highVal > 21)
SET @highVal = @lowVal;
IF (@lowVal > 21) --L
BEGIN
SET @Lcount += 1;
UPDATE dbo.CardTable
SET Status = 'L', Process = @process, Locked = 0
WHERE CardID = @iterator;
SET @slwb = 1;
SET @numCards = 0;
SET @lowVal = 0;
SET @highVal = 0;
END
ELSE
IF (@lowVal = 21 OR @highVal = 21)
BEGIN
IF (@numCards = 2)
BEGIN
SET @Bcount += 1;
UPDATE dbo.CardTable
SET Status = 'B', Process = @process, Locked = 0
WHERE CardID = @iterator;
END
ELSE
BEGIN
SET @Wcount += 1;
UPDATE dbo.CardTable
SET Status = 'W', Process = @process, Locked = 0
WHERE CardID = @iterator;
END
SET @slwb = 1;
SET @numCards = 0;
SET @lowVal = 0;
SET @highVal = 0;
END
ELSE
IF (@lowVal > 16 OR @highVal > 16)
BEGIN
SET @Scount += 1;
UPDATE dbo.CardTable
SET Status = 'S', Process = @process, Locked = 0
WHERE CardID = @iterator;
SET @slwb = 1;
SET @numCards = 0;
SET @lowVal = 0;
SET @highVal = 0;
END
ELSE
BEGIN
UPDATE dbo.CardTable
SET Status = '', Process = @process, Locked = 0
WHERE CardID = @iterator;
END
IF (@slwb = 1 AND (@status='S' OR @status='L' OR @status='W' OR @status='B'))
BEGIN
SET @iterator = @numRows;
IF (@status = 'S')
SET @SCount -= 1;
ELSE
IF (@status = 'L')
SET @LCount -= 1;
ELSE
IF (@status = 'W')
SET @WCount -= 1;
ELSE
SET @BCount -= 1;
END
ELSE
SET @iterator += 1;
END
IF (@prevproc < @process)
SET @iterator = @numRows;
END --Loop
UPDATE dbo.StatusTable
SET Deals += @Lcount
WHERE Status = 'L';
UPDATE dbo.StatusTable
SET Deals += @Scount
WHERE Status = 'S';
UPDATE dbo.StatusTable
SET Deals += @Wcount
WHERE Status = 'W';
UPDATE dbo.StatusTable
SET Deals += @Bcount
WHERE Status = 'B'
END --PROCEDURE
Sergey
New Member
New Member
Posts: 16


--
11 Dec 2015 11:11 PM
Tornbjörn, nu förstår jag vad du menar med
det räcker att två procedurer kommer fram till någon "stoppstatus" (S/L/W/B) för samma kort, så är de i synk därefter
- det är sant, och det verkar vara mycket sannolikt att inträffa inom första 20 kort i överlappet. Tummen upp! Detta är en smart upptäckt som jag önskar ha kommit på själv . Du verkar ha ensamrätt på den.

Eller var det någon annan som sett den möjligheten?

//Sergey
Jonas
New Member
New Member
Posts: 13


--
14 Dec 2015 09:11 AM
Jag såg artikeln i http://techworld.idg.se/2.2524/1.645115/sql
och funderar på vad Johan menar med nedan;

– En viss hantering av tecken krävdes, vilket till exempel innebar att man måste vara noga med användning av stora och små bokstäver för kolumnnamn, säger Johan Åhlén

Själva SQL koden är väl inte case sensitive?

Kan ju även vara journalisten som missat nått, efter som uppgiften är felbeskriven i artikeln.
Jonas
New Member
New Member
Posts: 13


--
04 Jan 2016 08:17 AM
Hej igen,

Finns det en möjlighet att ta del av resultatet för alla 15 godkända bidrag?
Tackar!
JAhlen
Veteran Member
Veteran Member
Posts: 144


--
05 Jan 2016 04:18 PM
Hej!

Nu är resultatsidan uppdaterad med samtliga godkända bidrag (dock bara det bästa från varje tävlande).

Om du inte står med så är det för att ditt bidrag inte godkändes.

MVH
Johan
JAhlen
Veteran Member
Veteran Member
Posts: 144


--
05 Jan 2016 04:26 PM
Det jag egentligen sade (men som omformulerades av journalisten) var att vi körde med en case-sensitive collation (vilket står specat i uppgiften på hemsidan). Därmed blev det även viktigt med case på kolumnamn och liknande i SQL-koden.

Några av tävlingsbidragen föll på detta.

MVH
Johan


Posted By Jonas on 2015-12-14 09:11
Jag såg artikeln i http://techworld.idg.se/2.2524/1.645115/sql
och funderar på vad Johan menar med nedan;

– En viss hantering av tecken krävdes, vilket till exempel innebar att man måste vara noga med användning av stora och små bokstäver för kolumnnamn, säger Johan Åhlén

Själva SQL koden är väl inte case sensitive?

Kan ju även vara journalisten som missat nått, efter som uppgiften är felbeskriven i artikeln.


You are not authorized to post a reply.
Page 3 of 3 << < 123