2012-03-28 10 views
5

Abbiamo un sistema in cui ai clienti viene assegnato un prodotto in base all'ordine di arrivo.Soluzione ottimale per un numero elevato di richieste su una tabella di database

La nostra tabella prodotti contiene una chiave primaria incremento che ha iniziato a zero che usiamo per tenere traccia di quanti prodotti sono stati assegnati ad esempio un utente si riserva un prodotto e viene assegnato 1, prossimo utente ottiene 2 ecc

Il problema è che potenzialmente centinaia di migliaia di utenti accederanno al sistema in qualsiasi ora. Tutti quelli che colpiranno questo tavolo unico.

Poiché è necessario garantire che a ogni cliente venga assegnato un solo prodotto e tenere traccia di quanti prodotti sono stati allocati, utilizziamo un blocco riga per ogni cliente che accede al sistema per assicurarsi che scriva sulla tabella prima del prossimo cliente colpisce il sistema, vale a dire applica la regola "primo arrivato primo servito".

Siamo preoccupati per il collo di bottiglia che è il tempo di elaborazione di ciascuna richiesta in entrata SQL Server 2008 Enterprise Edition e il blocco riga.

Non è possibile utilizzare più server poiché è necessario garantire l'integrità della chiave di accesso in modo che tutto ciò che richiede la replica non funzioni.

Qualcuno sa di buone soluzioni particolarmente efficienti nel gestire un numero elevato di richieste su una tabella di database?

Un po 'più informazioni: La tabella in questione contiene essenzialmente solo due campi: ID e ID cliente. La soluzione è per un omaggio gratuito di un milione di prodotti - da qui l'aspettativa di una forte domanda e perché utilizzare la chiave primaria incrementale come chiave ha senso per noi - una volta che la chiave raggiunge un milione, non è più possibile registrare clienti. Inoltre, i prodotti sono tutti diversi, quindi l'allocazione della chiave corretta è importante per es. i primi 100 clienti inseriti hanno ricevuto un prodotto di valore superiore rispetto ai successivi 100 ecc.

Grazie per qualsiasi aiuto.

+1

Puoi re-taggare, includere [sqlserver] e puoi dirmi la versione e l'edizione, se modifichi la tua domanda e dicci di avere 'SQL2008 Enterprise Edition', ad esempio potremmo essere in grado di offrire soluzioni su misura per es. Il partizionamento delle tabelle è disponibile in SQL 2008 EE –

+0

Grazie Jeremy. Aggiunte le informazioni aggiuntive. –

+0

Prima domanda ovvia; hai rimosso tutto il resto dalla transazione che ottiene la chiave? Per esempio. sai prima di provare a ottenere la chiave tutto ciò che devi sapere, andare al tavolo a prendere la chiave e sbloccare prima di fare altre cose? – Karl

risposta

5

Innanzitutto, per rimuovere il problema della generazione di chiavi, li genererei tutti in anticipo. È solo a 1 milione di righe e significa che non devi preoccuparti di gestire il processo di generazione delle chiavi. Significa anche che non devi preoccuparti di generare troppe righe accidentalmente, perché una volta riempita la tabella, farai solo UPDATE, non INSERT.

Una domanda importante qui è, sono tutti gli articoli di 1 m identici o no? Se lo sono, allora non importa in che ordine sono le chiavi (o anche se hanno un ordine), così come i clienti inviano richieste, semplicemente "prova" ad AGGIORNARE il tavolo qualcosa di grosso come questo:

UPDATE TOP(1) dbo.Giveaway -- you can use OUTPUT to return the key value here 
SET CustomerID = @CurrentCustomerID 
WHERE CustomerID IS NULL 

IF @@ROWCOUNT = 0 -- no free items left 
PRINT 'Bad luck' 
ELSE 
PRINT 'Winner' 

Se invece gli articoli da 1 m sono diversi, è necessaria un'altra soluzione, ad es. l'articolo 1 è X, gli articoli 2-10 sono Y, 11-50 sono Z ecc. In questo caso è importante assegnare i clienti alle chiavi nell'ordine in cui vengono inoltrate le richieste, quindi probabilmente dovresti esaminare un sistema di accodamento di qualche tipo, forse usando Service Broker. Ogni cliente aggiunge una richiesta alla coda, quindi una stored procedure li elabora uno alla volta e assegna loro la chiave libera MAX, quindi restituisce i dettagli di ciò che ha vinto.

+0

'SET ROWCOUNT' è deprecato in SQL 2008. Usa invece 'UPDATE TOP (1)'? http://msdn.microsoft.com/en-us/library/ms188774%28v=sql.100%29.aspx –

+0

@EdHarper Sì, questo è un buon punto e ho aggiornato il mio esempio. Sebbene il messaggio chiave per l'OP sia, naturalmente, non importa quale riga aggiorni finché ne aggiorni una sola. – Pondlife

+0

Grazie Pondlife. Gli elementi sono diversi, quindi sembra che l'accodamento sia la strada da percorrere e accetti solo che ci sarà un certo ritardo nell'elaborazione di ogni richiesta nei momenti di punta. Un'altra soluzione a cui stavo pensando era di collocare tutti i numeri dispari in un database e persino in un altro database, quindi disporre di un bilanciamento del carico con un semplice switch di bit che invia clienti alternativi a un database. Sto indovinando che probabilmente sto spostando il collo di bottiglia per il bilanciamento del carico invece e che probabilmente finirà per aver bisogno di una coda troppo? Grazie per il vostro aiuto, molto apprezzato. –

Problemi correlati