Индексы и OR

algo

To the stars!
Наверно, что-то криво затюнено, или индекс большой.

Покажи show create table / my.cnf
 

chira

Новичок
Vsevolod

всё это очень подозрительно ...
2.5 секунды для 250 записей ... если то, что ты написал всё правда, то нужно искать в другом месте ...
попробовать теже данные и запросы на другом железе
 

walrus

Новичок
chira
да, у меня записей возвращается порядка 10% от общего количества в этом примере. В реальном проекте выборка у меня гораздо меньше, обычно когда даже пик посещаемости - 20 пользователей онлайн, то по мониторингу вижу, что сервак спокойно со всем справляется, очереди из запросов не создается.
 

Vsevolod

Новичок
Автор оригинала: chira
Vsevolod

всё это очень подозрительно ...
2.5 секунды для 250 записей ... если то, что ты написал всё правда, то нужно искать в другом месте ...
попробовать теже данные и запросы на другом железе
какая разница сколько записей возвращается? он просматривает 90.000 строк и не использует индексов. дело в этом.

-~{}~ 10.04.07 11:12:

250 записей - это возвращаемые записи в результате выборки из таблицы размером 90.000 записей.

-~{}~ 12.04.07 10:14:

Автор оригинала: algo
Наверно, что-то криво затюнено, или индекс большой.

Покажи show create table / my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Default to using old password format for compatibility with mysql 3.x
# clients (those using the mysqlclient10 compatibility package).
default-character-set=cp1251
character-set-server=cp1251
collation-server=cp1251_general_ci
init-connect="SET NAMES cp1251"
skip-character-set-client-handshake
old_passwords=1
ft_min_word_len=3
ft_stopword_file=null
long_query_time=20
log-slow-queries=/var/log/mysqld/slowquery.log

[mysql.server]
user=mysql
basedir=/var/lib

[mysqld_safe]
err-log=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
key_buffer_size=64M
sort_buffer_size=4M
table_cache=256
read_buffer_size=1M
ft_min_word_len=3



[mysqldump]
default-character-set=cp1251
 

chira

Новичок
Vsevolod

ради интереса создал, у себя на компе, таблицу с двумя полями INT, VARCHAR(20)
нагенерил 1 000 000 записей
таблица получилась ~20MB
Код:
mysql> select count(*) from t;
+----------+
| count(*) |
+----------+
|  1000000 |
+----------+
1 row in set (0.00 sec)

mysql> select * from t where n1 like '%VV%' or n1 like '%MM%' limit 2000,10
    -> ;
+------+---------+
| f1   | n1      |
+------+---------+
|   77 | VVN"!\J |
|   58 | /91(VVM |
|   46 | HOPFMM: |
|   78 | VVKU'%$ |
|   99 | ?>VVHI2 |
|   11 | GMM8PI[ |
|   75 | '2&FMM: |
|   86 | T=VVJPP |
|   37 | 2/5\MM9 |
|   58 | F.5\MM; |
+------+---------+
10 rows in set (0.41 sec)

mysql> select count(*) from t where n1 like '%VV%' or n1 like '%MM%';
+----------+
| count(*) |
+----------+
|     2829 |
+----------+
1 row in set (0.61 sec)

mysql> select version();
+-------------------------+
| version()               |
+-------------------------+
| 4.1.21-community-max-nt |
+-------------------------+
1 row in set (0.00 sec)
запрос занимает меньше секунды при полном сканировании таблицы ...
настройки MySQL минимальные, из my.ini:

key_buffer = 16K
max_allowed_packet = 2M
table_cache = 4
sort_buffer_size = 64K
read_buffer_size = 256K
read_rnd_buffer_size = 256K
net_buffer_length = 2K
thread_stack = 64K


твоя таблица сколько мегов?
 

Vsevolod

Новичок
хм.. 11Мб. А что за сервер? это в момент без нагрузки?

у тебя в запросе поиск только по n1, а если будет n1 like 'VV%' or n2 like 'MM%'

?

-~{}~ 12.04.07 21:32:

Вот еще какое наблюдение: время выполнения значительно зависит от числа возвращаемых строк.

например по запросу

select * from oxid_artist where n1 like 'aa%' or n2 like 'bb%'

выводится 46 строк за 0.6 секунды

по запросу

select * from oxid_artist where n1 like 'a%' or n2 like 'b%'

около 4000 за 5.5 секунд

инексы не используются, mysql в обоих случая должен пройти 90.000 строк.

-~{}~ 12.04.07 21:35:

т.е. если к примеру запрос
select * from oxid_artist where n1 like 'aa%' or n2 like 'bb%'

выполняется за 0.6 секунды, значит этого времени ему хватает на то, чтобы обойти 90.000 строк.

На что расходуется остальное время при возвращении больших результатов?
 

Vsevolod

Новичок
n1 like 'aa%' or n2 like 'bb%' limit 50 возвращает 46 строк за 0.6сек

n1 like 'a%' or n2 like 'b%' limit 50 возвращает 50 строк за 0.16 сек

во втором случае все понятно - он не проходит по всем 90.000 а останавливается как только найдет 50 строк. поэтому и быстрее

добавляем order by n1,n2 чтобы заставить его пройти всю таблицу. при запросе будет использован filesort.
запрос длиться 0.7 сек
 

.des.

Поставил пиво кому надо ;-)
В большинстве случаев когда нужны подобные выборки это свидетельство неправильного дизайна бд.

А по существу запрос с OR и LIKE %% будет медленным по определению.
10-20MB может преобразовать таблицу в HEAP?
 

Vsevolod

Новичок
heap не пойдет.
1. памяти и так немного
2. есть и другие не менее важные таблицы. все в память не загнать
3. таблица будет увеличиваться. со временем сильно
 

phprus

Moderator
Команда форума
.des.
А где в этой теме используются такие запросы? Я вижу только запросы вида LIKE 'что_то%' , а такие запросы используют индексы и работают достаточно быстро.
 
Сверху