OVH Community, your new community space.

Come aumentare query sql


gio01
29.01.2010, 15.05
Garzie ho risolto... avevo un problema con gli indici adesso ho risolto Grazie

Ego-Ale-Sum
26.01.2010, 13.09
non è necessario riavviare il database: si tratta soltanto di un'alterazione alle strutture delle tabelle.
comunque... non so cosa tu abbia combinato ma o hai sbagliato a mettere qualche indice (hai messo anche indici UNIQUE o chiavi primarie?) oppure è un baco nel codice...

gio01
26.01.2010, 10.18
Ho mesos le key con Navicat nelle varie tabelle giusto? key 1 key 2 key 3 ecc ecc
ho salvato e riavviato,
Dopo di che uno si teleportava verso un altro luogo e gli si ca,biavano da soli i bonus ecc ecc..
poi altro problea. Double key c'è ci sn stessi id con doppie key.. e vorrei eliminarle...

Ego-Ale-Sum
26.01.2010, 09.17
Se hai seguito quello che ti ho detto e hai creato gli indici giusti, questo non è possibile: gli indici non fanno altro che creare una copia di alcuni dati.
Se i dati non vengono salvati o sono "in disordine" (che non ho capito cosa significhi), è un problema del tuo script...
Che indici hai creato?

gio01
26.01.2010, 09.11
Ti ringrazo tantissimo di quello che hai detto ma... devo dirti che...
si e + veloce nelk caricare ecc ecc ma... non salva del tutto e salva in disordine...

Ego-Ale-Sum
24.01.2010, 19.42
Citazione Originariamente Scritto da Giampaolo
Eccellente! I miei complimenti!
grazie

Giampaolo
24.01.2010, 19.37
Citazione Originariamente Scritto da Ego-Ale-Sum
Allora...
Eccellente! I miei complimenti!

Ego-Ale-Sum
24.01.2010, 19.14
Allora...

In MySQL esistono 2 tipi di indici:
1. chiavi primarie
2. indice
esiste anche un terzo tipo di indice (supportato solo da MyISAM): fulltext. questo, però, non ci interessa, in quanto ha a che fare con la ricerca di testo all'interno di stringhe, e non con l'ottimizzazione della ricerca di un record.

le chiavi primarie sono un valore che identifica univocamente un record della tabella. ogni tabella può avere AL MASSIMO 1 colonna con una chiave primaria, e, nonostante non sia obbligatoria, ti consiglio di crearne SEMPRE una.
Di solito la chiave primaria è un numero intero che rappresenta l'ID del record, e spesso ha anche l'auto increment.

Gli indici "normali", invece, servono ad ottimizzare la ricerca di un valore.
Ad esempio, se tu hai una colonna "Nome" che usi spesso in una query di ricerca (es. "SELECT * FROM tabella WHERE nome = 'Mario'"), puoi pensare di renderla indice. In questo modo il MySQL memorizzerà il nome, oltre che nella riga, anche in un'altra struttura, organizzata in modo tale da rendere la ricerca di quel valore più veloce.
Quando tu cerchi 'Mario' nel campo nome, quindi, il database non va a cercare direttamente nei record, ma cerca in quell'altro "archivio" (che in realtà è un BTREE, se sai un po' di teoria degli alberi). Appena trova una riga con nome 'Mario', quindi, va a prelevare il record avente quella chiave primaria.
Gli indici possono anche essere di tipo "UNIQUE": in questo modo, non sono ammessi valori duplicati (nell'esempio di prima, se c'è già una persona di nome 'Mario' nella tabella, cercare di inserire un'altra persona con quel nome darà un errore). Le chiavi uniche spesso sono molto comode, anche se rallentano un po' l'inserimento dei dati (di molto poco; tuttavia, meglio non abusarne ).

Per creare un indice si può usare PHPMyAdmin: nella visualizzazione struttura della tabella, basta cliccare in uno dei 3 bottoni qui sotto:
http://img693.imageshack.us/img693/4...0124a20105.png
Il primo crea una CHIAVE PRIMARIA in quella colonna; il secondo un INDICE ("normale"); il terzo un indice UNIQUE. Il quarto bottone serve invece a creare indici fulltext; qui è grigio perchè non è un campo di tipo text.

Esempio: una tabella che deve memorizzare dei messaggi (ad esempio messaggi privati di un forum ecc).
Ci saranno i seguenti campi:
- id_messaggio, di tipo bigint (intero a 64 bit) unsigned: l'ID del messaggio. Ha l'autoincrement
- mittente, di tipo intero (l'id dell'utente mittente)
- destinatario, di tipo intero (l'id dell'utente destinatario)
- ora, di tipo intero (timestamp unix)
- letto, di tipo tinyint
- testo, di tipo text
In una tabella del genere, io creerei i seguenti indici:
-id_messaggio di tipo CHIAVE PRIMARIA (tra l'altro, l'essere chiave primaria è condizione necessaria per poter usare l'autoincrement)
- mittente, con un indice "normale"
- destinatario, con anche qui un indice "normale"
- ora, altro indice "normale"

questo perché generalmente le query saranno sempre del tipo:
SELECT * FROM messaggi WHERE mittente = XXX
SELECT * FROM messaggi WHERE destinatario = XXX AND letto = 0
SELECT * FROM messaggi WHERE mittente = XXX AND ora > YYY

Nota che non ho reso il campo "letto" indice: non è necessario che ogni campo che appare in una clausula WHERE lo sia.
In questo caso, infatti, la ricerca sarà prima fatta per il mittente, e poi filtrata con letto. Creare un indice su letto non porterebbe alcun vantaggio reale.

Spero di essere stato abbastanza chiaro.
Intanto, prova a fare questo: ti garantisco che l'aumento delle performance sarà enorme.

Se non dovesse bastare, poi, passiamo ai livelli successivi (caching e uso di database non relazionali).

Ego-Ale-Sum
24.01.2010, 17.17
Con PHPMyAdmin sono pochi click, in visualizzazione struttura. È molto semplice CREARE gli indici.

Piuttosto, più interessante sarebbe la domanda: DOVE li creo? e di QUALE TIPO?
Per risponderti devo fare un po' di teoria e qualche esempio. Adesso devo uscire, ma se aspetti un paio d'ore che torno a casa ti scrivo giù una piccola guida

gio01
24.01.2010, 17.09
( era sott'inteso )
come si creano? scusami se sono un pò imbranato

Ego-Ale-Sum
24.01.2010, 17.04
In due parole? Visto che non ho ancora capito se l'hai già fatto...
Creare gli indici
(ok sono 3 parole )

gio01
24.01.2010, 17.02
Bene ti ringrazio per le dritte
La cosa la vedo difficile per il mio punto da realizzare ma ci devo riuscire se voglio che i miei progetti vengono benissimo
Quindi cosa mi consigli di fare in due parole?

Ego-Ale-Sum
24.01.2010, 16.30
Oddio... Mi sa che non hai capito te quello che intendevo

Intanto, il punto 2 non significa che non devi usare MySQL, ma che, nello script, se qualcosa non richiede *obbligatoriamente* un database relazionale, puoi pensare a spostarla su un altro database. In sostanza, usare sia MySQL che CouchDB/MongoDB. La differenza, in termini di prestazioni, tra database relazionali e non relazionali è enorme.

Ad esempio, se devo salvare i dati degli utenti, li metto per forza in un database relazionale (perchè, in questo modo, posso collegare diverse tabelle, fare query complicate ecc).
Però, nel mio sito, ogni tanto devo anche memorizzare dei "token" (per l'accesso a servizi OAuth): non sono legati a nessun utente, ma devo memorizzare questa lista. In questo caso, quindi, NON uso MySQL, ma un database non relazionale. (Potrei usare anche memcached, ma in questo caso preferisco che i dati siano salvati in una memoria non volatile - memcached tiene tutto in RAM).

Quando tu dici "No mysql = No velocità e no accesso", mi sento in gran disaccordo: in realtà, MySQL, come tutti i database relazionali, introduce un enorme overhead: basti pensare che ogni volta deve interpretare la query, aprire le tabelle, selezionare i dati e cercare le relazioni. Però, i RDBMS sono comodissimi quando si devono salvare dati con relazioni.

In ogni caso, la prima cosa da fare, se non l'hai già fatto, è indicizzare le tabelle. Questo "piccolo" fatto rende le ricerche (e anche gli inserimenti) MOOOOLTO più veloce in tabelle con tanti record. Tanto per fare un esempio, in una tabella con 1.000.000 di record, la ricerca in un campo non indicizzato richiede in media 500.000 accessi; se il campo è indicizzato, invece, si riduce a SOLO 20 ACCESSI! (cioè log2(1.000.000) ) 25.000 volte meno! In termini più "matematici", si dice che la complessità della ricerca di un valore tra N record passa da lineare ( O(N) - in media, comunque, si parla di N/2 accessi) a logaritmica ( O(log2(N)) ).

Per quanto riguarda la replicazione... È una funzione standard di MySQL, ed è molto stabile.
Generalmente, però, la replicazione è asimmetrica: avendo 2 server A e B, il server A (master) è in lettura E scrittura, mentre B (slave) è in sola lettura.
Puoi avere molti server slave, ma solo 1 master. MySQL si arrangia ad occuparsi della replicazione, in modo molto efficiente.
Tuttavia, la replicazione asimmetrica può non portare vantaggi se hai molte operazioni in scrittura: va quindi bene per blog, portali ecc, ma non per social network, forum et similia.

Esiste quindi un'ultima opzione, cioè l'utiizzo di un "cluster". Questo può essere fatto "manualmente", usando tecniche come lo sharding (ma che si rivelano essere ENORMEMENTE complicate da gestire, quando devi stabilire le relazioni tra le tabelle), oppure con prodotti già pronti, tra cui MySQL Cluster.
Quest'ultimo è molto stabile e, avendo almeno 3 server, garantisce ottime prestazioni oltre che l'High Availability: se uno dei 3 server salta, il cluster continua a funzionare.
In particolare, soluzioni del genere sono davvero efficaci: basti pensare che FriendFeed si basa solamente su un cluster MySQL.

gio01
24.01.2010, 16.04
Citazione Originariamente Scritto da Ego-Ale-Sum
Innanzitutto è necessario ottimizzare.
Hai creato gli indici nelle tabelle dove necessario? È vero che occupano spazio (in alcune mie tabelle occupano addirittura metà della dimensione totale della tabelle), ma sono fondamentali. Inoltre, controlla la configurazione del MySQL e se necessario pensa a fare un po' di tuning. Tra le varie opzioni di tuning, ti consiglio anche di valutare l'utilizzo di Google Perftools (lo trovi nei repository di www.dotdeb.org - da qui io ho scaricato i pacchetti di PHP, MySQL e Perftools).

Fatto questo, pensa ad ottimizzare il codice:
1. Ci sono dei punti (e quasi sicuramente ce ne saranno) in cui è possibile utilizzare una cache? (memcached) Con PHP, l'utilizzo di memcached è semplicissimo, e l'aumento di prestazioni è enorme.
2. Nel MySQL avrai sicuramente salvato molti dati: è davvero necessario usare il MySQL per tutto questo? Ricorda che MySQL è un RDBMS, cioè un database relazionale: questo introduce un overhead enorme in certi casi. Dove non ti servono le relazioni tra le tabelle, quindi, valuta l'utilizzo di un database NON-relazionale, ad esempio CouchDB, MongoDB ecc ecc

L'ultima spiaggia è poi l'utilizzo di 2 o più server per MySQL, usando la replicazione (la quale, però, non è efficiente se il rapporto write/read delle tue query è alto, cioè se ci sono molte operazioni in scrittura rispetto a quelle in lettura) o creando un cluster.
bene ti ringrazio delle risposte.
Per il sito web va ok ( dovrei solo auentare le massime connessioni apache e poi dovrebbe andare meglio )
Per la parte 2 ovvero : é necessario mysql obbligatoriamente per queste cose?
SI!
Senza mysql ( senza salvataggio dati ) non funziona nulla e va in errore
No mysql = No velocità e no accesso
Per questo richiede Mysql
Beh usare 2 server ho + mysql non fosse una cattiva ideea xò lo script sito web va a prendere quel Database + Database da queriare
Se non è su quel ip non inserisce e va in errore
Ti faccio capire
DB Name è composto da : A= Login B= Poteri GM C= Player ,item , npc ecc ecc
Se il DB A non sta con C Non riesce a fare la query per bene e quindi va in errore
IL B può stare benissimo in un altro posto
ma i + più importanti sono A e C
Se si danneggia A = C non va
Se si danneggia C = A non va
non sò se hai capito

Ego-Ale-Sum
24.01.2010, 14.23
Innanzitutto è necessario ottimizzare.
Hai creato gli indici nelle tabelle dove necessario? È vero che occupano spazio (in alcune mie tabelle occupano addirittura metà della dimensione totale della tabelle), ma sono fondamentali. Inoltre, controlla la configurazione del MySQL e se necessario pensa a fare un po' di tuning. Tra le varie opzioni di tuning, ti consiglio anche di valutare l'utilizzo di Google Perftools (lo trovi nei repository di www.dotdeb.org - da qui io ho scaricato i pacchetti di PHP, MySQL e Perftools).

Fatto questo, pensa ad ottimizzare il codice:
1. Ci sono dei punti (e quasi sicuramente ce ne saranno) in cui è possibile utilizzare una cache? (memcached) Con PHP, l'utilizzo di memcached è semplicissimo, e l'aumento di prestazioni è enorme.
2. Nel MySQL avrai sicuramente salvato molti dati: è davvero necessario usare il MySQL per tutto questo? Ricorda che MySQL è un RDBMS, cioè un database relazionale: questo introduce un overhead enorme in certi casi. Dove non ti servono le relazioni tra le tabelle, quindi, valuta l'utilizzo di un database NON-relazionale, ad esempio CouchDB, MongoDB ecc ecc

L'ultima spiaggia è poi l'utilizzo di 2 o più server per MySQL, usando la replicazione (la quale, però, non è efficiente se il rapporto write/read delle tue query è alto, cioè se ci sono molte operazioni in scrittura rispetto a quelle in lettura) o creando un cluster.

gio01
24.01.2010, 12.57
Salve.
Uso un server x SOLO mysql
e un debian lenny5.0
e funziona tutto e va veloce
avrei un problema
.
siccome ho delle query abbastanza sostanziose e quando c'è molta più gente in gioco non sò come far andar veloce anche se ci sono molta gente
quindi qualcuno mi potrebbe aiutre a risolvere il problema?
quando sono 700 on nessun problemq
quando sueprano i 2000 iniziano l'intasamento
spero che mi potrete aiutare