Mysql sorgusu ile sorun

4 Cevap php

Bunu nasıl mysql sorgu optimize edebilirsiniz:

SELECT * 
FROM messages 
WHERE toid='".$mid."' 
  AND fromid='".$fid."' 
  OR (toid='".$fid."' AND fromid='".$mid."')  
  AND subject != 'something' 
order by id ASC LIMIT 0,5

Ben tek bir sayfada kullanıcılar arasında iletileri almak gerekir. Bu sorgu, id çok zaman ve sunucu kaynaklarına alarak. Bazı başka bir şekilde yapılabilir mi?

Teşekkürler.

4 Cevap

Umarım belki bu kendine bir mesaj göndererek bir kullanıcıyı engellemek için bazı mantık var olduğu göz önüne alındığında:

WHERE toid IN ($mid, $fid) AND fromid IN ($mid, $fid) AND subject <> 'something'

(toid, fromid) bir dizin koyun ve oldukça Tamam olmalıdır, bence.

Yazılı olarak, sorgu muhtemelen gerçek niyeti ihanet ediyor. İstenilen durum olduğunu olası görünüyor

WHERE ( ( toid='".$mid."' AND fromid='".$fid."' )
   OR   (toid='".$fid."'  AND fromid='".$mid."') 
      )
  AND subject != 'something' 

But, as written, the query will only apply the subject condition with the second (toid and fromid) clause.
Note that in the above, the inner parenthesis are extraneous; never the less it is often a good idea to include them to show the intended expression more explicitly.

Her iki durumda da, this query is a "hard[er]" query to resolve, OR tümcesi ve bir EŞİT DEĞİL yüklem nedeniyle. (Diğer stratejiler mümkün olmasına rağmen) OR yan tümcesi, genellikle sunucu iki alt sorgu sonuçlarını birleştirme neden olur. EŞİT DEĞİL yüklemi bir dizin arama) tarafından eldeki satır yüklemi karşılayan olmadığını değerlendirmek için ana tablo / diğer indekslere gezi kaydeder için, (ancak bir kaplama indeks bazı durumlarda yardımcı olur) çözülemez

Bağımsız olarak bu mümkün mantıksal sorunu, dizinleri ekleme birden fazla anahtar durum yardımcı olacaktır olacaktır. Ben şu önermek istiyorum:

  • romatizmal, fromId, konu
  • romatizmal, fromid

Ayrıca konuyu içeren endeksinin faiz sorgu yerine konuyu arama zorunda daha endeksinin kısmi bir tarama ile çözülecek sağlamaktır. Bu indeks bu sorgu için bir kaplama indeksi olarak kullanılacaktır.

Dizinleri ekleme INSERT, UPDATE ve DELETE işlemleri için performans azalır, ancak dikkat edin.

Edit: on the usability of the (toid,fromid, subject) index
First off, it is acknowledged that we need only one of the suggested indexes, i.e. if we have the (romatizmal, fromid, subject) index, the (romatizmal, fromid) one would be redundant (albeit possibly more efficient if subject was a relatively long column).
This said, the fact that the query uses a NOT EQUAL predicate on subject doesn't necessary exclude the use of the subject data in the (romatizmal, fromid, subject) index. The reason for that is that the [not equal] condition on subject can be resolved within the index (not requiring a match/merge or a lookup, i.e. akin to some "covering" logic)

Çifti bir dizin ekleme (toid, fromid). Yani ilgili mesajları bulmak ve hızlandırmak için sorgu endeksi kullanmanızı sağlayacak. Tek tek sütunların üzerinde indeksler hala potansiyel, bu mesajları / kişilerin birinden bir başkasına, yani taranacak iletilerin bir çok terk edeceğini unutmayın. Çifti kullanılarak iki kişi arasında sadece bu kadar dizin tarama tarafından bulunan mesajları sınırlayacaktır.

Zerkms işaret ettiği gibi, bu durumda konu için bir dizin yapamaz. Açıklamalarda önerisini edin.

Hem de kimlikleri için bir dizin ekleyin:

CREATE INDEX ids_index ON messages (fromid, toid);

ve ikiye bölünmüş sorgu.