2010-06-18 14 views

risposta

8

Una query illimitata è quella in cui i criteri di ricerca non è particolarmente preciso, ed è quindi probabile che torni un grande set di risultati. Una query senza una clausola WHERE rientrerebbe sicuramente in questa categoria, ma consideriamo per un momento alcune altre possibilità. Diciamo che abbiamo tabelle come segue:

CREATE TABLE SALES_DATA 
    (ID_SALES_DATA  NUMBER PRIMARY KEY, 
    TRANSACTION_DATE DATE NOT NULL 
    LOCATION   NUMBER NOT NULL, 
    TOTAL_SALE_AMOUNT NUMBER NOT NULL, 
    ...etc...); 

CREATE TABLE LOCATION 
    (LOCATION NUMBER PRIMARY KEY, 
    DISTRICT NUMBER NOT NULL, 
    ...etc...); 

Supponiamo che vogliamo tirare in una determinata operazione, e sappiamo l'ID della vendita:

SELECT * FROM SALES_DATA WHERE ID_SALES_DATA = <whatever> 

In questo caso la query viene delimitata, e possiamo garantire che accederà a una o a zero righe.

Un altro esempio di query limitata, ma con un grande set di risultati sarebbe quello prodotto quando il direttore del distretto 23 dice "Voglio vedere le vendite totali per ogni negozio nel mio distretto per ogni giorno dell'anno scorso", che sarebbe qualcosa di simile

SELECT LOCATION, TRUNC(TRANSACTION_DATE), SUM(TOTAL_SALE_AMOUNT) 
    FROM SALES_DATA S, 
     LOCATION L 
    WHERE S.TRANSACTION_DATE BETWEEN '01-JAN-2009' AND '31-DEC-2009' AND 
     L.LOCATION = S.LOCATION AND 
     L.DISTRICT = 23 
    GROUP BY LOCATION, 
      TRUNC(TRANSACTION_DATE) 
    ORDER BY LOCATION, 
      TRUNC(TRANSACTION_DATE) 

in questo caso la query deve restituire 365 (o meno, se i negozi non sono aperti tutti i giorni) righe per ogni negozio nel quartiere 23. Se c'è 25 negozi nel quartiere sarà restituire 9125 righe o meno.

D'altro canto, supponiamo che il nostro VP di vendita desideri alcuni dati. Non è abbastanza sicuro di cosa si voglia, ma è abbastanza sicuro che qualunque cosa sia successa nei primi sei mesi dell'anno ... non sono proprio sicuro di quale anno ... e Non sono sicuro della posizione, forse - probabilmente nel distretto 23 (ha avuto una faida con l'individuo che gestisce il distretto 23 negli ultimi 6 anni, da quel torneo di golf in cui ... beh, non importa. ..ma se un problema può essere appeso alla porta del direttore del distretto 23 così sia!) ... e naturalmente lui/lei/lei vuole tutti i dettagli, e averlo sulla sua scrivania molto dolce! E così otteniamo una query che assomiglia a qualcosa di simile

SELECT L.DISTRICT, S.LOCATION, S.TRANSACTION_DATE, 
     S.something, S.something_else, S.some_more_stuff 
    FROM SALES_DATA S, 
     LOCATIONS L 
    WHERE EXTRACT(MONTH FROM S.TRANSACTION_DATE) <= 6 AND 
     L.LOCATION = S.LOCATION 
    ORDER BY L.DISTRICT, 
      S.LOCATION 

Questo è un esempio di una query illimitata. Quante righe restituirà? Buona domanda: dipende da come sono state le condizioni di business, quanti luoghi sono stati aperti, quanti giorni ci sono stati a febbraio, ecc.

Metti più semplicemente, se puoi guardare una query e avere una buona idea di come molte righe saranno restituite (anche se quel numero potrebbe essere relativamente grande) la query è limitata. Se non puoi, è illimitato.

Condividi e divertiti.

0

http://hibernatingrhinos.com/Products/EFProf/learn#UnboundedResultSet

un set di risultati illimitata è dove una query viene eseguita e non limita in modo esplicito il numero di risultati restituiti da una query. Di solito, ciò significa che l'applicazione presuppone che una query restituirà sempre solo pochi record. Funziona bene nello sviluppo e nei test, ma è una bomba ad orologeria in attesa di esplodere in produzione.

La query potrebbe improvvisamente iniziare a restituire migliaia e migliaia di righe e, in alcuni casi, potrebbe restituire milioni di righe. Ciò porta a un maggiore carico sul server del database, sul server delle applicazioni e sulla rete. In molti casi, può arrestare l'intero sistema, di solito terminando con i server delle applicazioni che si bloccano con errori di memoria insufficiente.

Ecco un esempio di una query che attiverà il sconfinata avvertimento set di risultati:

var query = from post in blogDataContext.Posts 
      where post.Category == "Performance" 
      select post; 

Se la categoria delle prestazioni ha molti messaggi, stiamo andando a caricare tutti loro, che probabilmente non è quello che era previsto. Questo può essere risolto abbastanza facilmente usando l'impaginazione utilizzando il metodo Take():

var query = (from post in blogDataContext.Posts    
      where post.Category == "Performance"    
      select post) 
      .Take(15); 

Ora siamo certi che abbiamo solo bisogno di gestire un prevedibile, piccolo set di risultati, e se abbiamo bisogno di lavorare con tutti loro, possiamo sfogliare i record secondo necessità. L'impaginazione viene implementata utilizzando il metodo Skip(), che indica a Entity Framework di saltare (a livello di database) N numero di record prima di passare alla pagina successiva.

Ma v'è un altro evento comune del risultato illimitata impostato problema di attraversare direttamente l'oggetto grafico, come il seguente esempio:

var post = postRepository.Get(id); 
foreach (var comment in post.Comments) 
{ 
    // do something interesting with the comment 
} 

Qui, di nuovo, stiamo caricando l'intero set senza riguardo per quanto grande il risultato può essere. Entity Framework non fornisce un buon modo di sfogliare una collezione quando si attraversa il grafico dell'oggetto. Si consiglia di inviare una query separata ed esplicita per i contenuti della raccolta, che consentirà di scorrere la raccolta senza caricare troppi dati nella memoria.

Problemi correlati