2016-04-20 10 views
7

Ho spostato alcune tabelle del mio database che hanno avuto problemi con il traffico verso un altro server e non voglio usare le tabelle federate per un sacco di motivi (le prestazioni sono la ragione principale). Quindi devo creare 2 connessioni diverse nella mia classe PHP e riscrivere le mie query nel codice che è entrato tra tabelle da server diversi.Mysql Query su server senza l'utilizzo della tabella federata

Ad esempio, ho due tabelle: Utenti ed Enterprise che si trovano in server diversi.

Quando era sullo stesso server, la query è stata:

select name from Enterprise E 
inner join Users U on E.cod = U.cod 
where E.cod = $my_code and U.codUsers in ($users); 

Così ho cambiato a questo:

$rst= select group_concat(U.cod) from Users as U 
where U.codUsers in ($users) 

select name from Enterprise E 
where E.cod = $mycode and E.cod in ($rst); 

mia domanda è, come posso simillary fare questo quando ho questo tipo di query:

select e.name, e.datebegin, e.dateend from Enterprise E 
leftjoin (select h.callQuantity, h.history from thirdtable 
     inner join Users u on e.cod = u.cod 
     where u.codHistory in (1,2,3) 
      group by u.cod) 

La mia domanda è chiara? Ci scusiamo per il mio inglese

+1

Ciao Shermano? A quale server appartiene "terzo classificato"? –

+1

La query che si desidera refactor ha un problema con la sintassi: leftjoin => left join; thirdtable non ha un nome alias; e.cod non appartiene alla subquery; la tabella derivata non ha alias; a sinistra si unisce senza condizioni? –

risposta

10

Prima di tutto, le tabelle federate sono la soluzione migliore (sono fatte esattamente per quel tipo di cose che si sta tentando di fare a mano). Ma non li vuoi, quindi ecco la cosa migliore:

Per qualcosa di più complicato del tuo primo esempio, dovresti simulare manualmente una tabella remota inserendo il contenuto della tabella invece della tabella.

Riscriverò il tuo primo esempio in questo modo, perché il tuo secondo esempio è incasinato e non so nemmeno cosa tu voglia esprimere esattamente lì.

hai avuto il seguente codice quando si utilizza 1 server:

select name from Enterprise E 
inner join Users U on E.cod = U.cod 
where E.cod = $my_code and U.codUsers in ($users); 

È ora possibile sostituire la tabella con i dati effettivi della tabella:

select name from Enterprise E 
inner join 
    (  select 1 as cod, 4 as codUsers, 20 as codHistory 
    union select 2 as cod, 8 as codUsers, 500 as codHistory 
    union select 3 as cod, 29 as codUsers, 100 as codHistory 
    ) as U 
on E.cod = U.cod 
where E.cod = $my_code and U.codUsers in ($users); 

Per fare questo, è necessario costruire i dati della tabella come una stringa (sto usando DOP qui):

foreach($db->query('select * from Users U where U.codUsers in ($users)') as $row) { 
    if($data !== '') { $data .= 'union '; } 
    $data .= 'select ' . $row['cod'] . ' as cod, ' 
      . $row['codUsers'] . ' as codUsers, ' 
      . $row['codHistory'] . ' as codHistory '; 
} 

bisogna adattarsi al layout del vostro Us tavolo-ovviamente (e non dimenticare un po 'per le stringhe), e puoi omettere le colonne che non ti servono.

È ora possibile inserire la stringa ovunque tu avessi gli utenti-tavolo prima e scrivere il codice come se fosse su 1 server, in modo che il primo codice sarebbe simile

select name from Enterprise E 
inner join ($data) as U on E.cod = U.cod 
where E.cod = $my_code and U.codUsers in ($users); 

e il secondo codice (anche se vi ricordo che è rotto per cominciare e non avrebbe funzionato sul 1 server o) sarebbe simile

select e.name, e.datebegin, e.dateend from Enterprise E 
leftjoin (select h.callQuantity, h.history from thirdtable 
     inner join ($data) as u on e.cod = u.cod 
     where u.codHistory in (1,2,3) 
      group by u.cod) 

è necessario assicurarsi di avere solo un piccolo numero di utenti nella vostra $ data-string, allora questo funzionerà bene Altrimenti, hai davvero bisogno di tabelle federate.

+0

Grazie per l'uomo delle risposte! Sono certo che Federate Tables può risolvere facilmente questo problema, ma non mi piace come funzioni questa funzione, Federate Tables non usa indici, ho fatto un test qui qualche giorno fa e le prestazioni della query sono state disgustose. Ma davvero grazie per la tua risposta, mi ha aiutato molto! – Shermano

1

Piano A:

recuperare i dati che potrebbero essere necessari da una macchina; metti il ​​set di risultati in un array associativo.

Fate lo stesso per la seconda macchina. (E terzo ...)

Gioca con i due array.

Plan B (simile al vostro primo caso):

recuperare i dati che potrebbero essere necessari da una macchina; metti il ​​set di risultati in un array associativo.

Costruire un IN (...); aggiungilo alla query per la seconda macchina.

Recupera dalla seconda macchina.

(ecc.)

Giocare con i risultati.

Il piano B può essere 'ottimizzato' se si sa quale macchina avrà il set di risultati più piccolo e cominciando da essa.

PHP ha una vasta gamma di funzioni di array, rendendo molte delle manipolazioni facili.

+0

Grazie amico, sto provando una soluzione simile qui, grazie davvero! – Shermano

Problemi correlati