|
|
|
| Из таблицы test_buf извлекаю уникальные значения IP и useragent. В таблице порядка десяти тысяч записей, но запросы
SELECT DISTINCT ip AS cnt FROM test_buf
SELECT DISTINCT useragent AS cnt FROM test_buf
| выполняются настолько медленно, что скрипт через раз зависает.
Что бы ускорить этот процесс, хотел проиндексировать таблицу по этим колонкам. Но синтекс не складывается, как ни пытался!
CREATE INDEX test_buf ON ip, useragent (useragent(99))
|
Сообщение - Table 'useragent' doesn't exist
Поля VARCHAR
Как осуществляется CREATE INDEX ? | |
|
|
|
|
|
|
|
для: Владимир55
(18.05.2009 в 13:13)
| | Дело в том, что после ключевого слова ON должно идти название таблицы. Один вызов оператора CREATE INDEX - создается один индекс (он может быть и по нескольким столбцам, однако, вам сейчас нужно два индекса - поэтому нужно два оператора CREATE INDEX). Причем после CREATE INDEX идет название индекса (может совпадать с названием столбца), а после ON - название таблицы. В скобках, через запятую идут названия столбцов по которым создается индекс - если столбец один - он просто указывается (это как раз ваш случай и эта часть запроса написана правильно). | |
|
|
|
|
|
|
|
для: cheops
(18.05.2009 в 13:32)
| | Я сделал вот так:
mysql_query("TRUNCATE TABLE test_buf");
mysql_query("CREATE INDEX useragent ON test_buf (useragent(89))");
mysql_query("CREATE INDEX ip ON test_buf (ip(18))");
|
Первый раз запустил скрипт - диагностика не сообщает о наличии проблем.
А после второго запуска получаю сообщение:
1061 98 : Duplicate key name 'useragent'
1061 98 : Duplicate key name 'ip'
|
Почему так? Ведь таблица полностью очищена!
(А может быть каждая индексация добавляет к таблице дополнительный невидимый в PhpMyAdmin столбец, куда при INSERT INTO записывается информация в спеwиальном виде, более подходящим для поиска?
Если так, то не лучше ли CREATE INDEX выполнять непосредственно при создании таблицы сразу после CREATE TABLE ?
CREATE INDEX для данной таблицы выполняется однократно? Можно и для пустой таблицы?
Или каждый раз перед каждым ресурсоемким поиском для предварительной индексации накопившейся информации?) | |
|
|
|
|
|
|
|
для: Владимир55
(18.05.2009 в 14:32)
| | а зачем Вам на одно поле 2 раза создавать индексы?
- создал таблицу
- поставил индексы
и все, больше индексы не трогают. | |
|
|
|
|
|
|
|
для: а-я
(18.05.2009 в 16:46)
| | "зачем Вам на одно поле 2 раза создавать индексы?"
cheops писал: "вам сейчас нужно два индекса - поэтому нужно два оператора CREATE INDEX"
- создал таблицу
- поставил индексы
Так все же два оператора или один? | |
|
|
|
|
|
|
|
для: Владимир55
(18.05.2009 в 17:25)
| | для каждого индекса отдельный оператор.
Только выполнять каждый нужно не более одного раза.
Насколько мне известно truncate не имеет никакого отношения к индексам.
Также можете ознакомиться со следующим:
http://dev.mysql.com/doc/refman/5.0/en/show-index.html
http://dev.mysql.com/doc/refman/5.0/en/drop-index.html | |
|
|
|
|
|
|
|
для: Root
(18.05.2009 в 17:39)
| | Я английского не знаю, так что посмотреть не удалось.
Но скажите, будет ли верно, если я однократно после создания таблицы запущу операторы
mysql_query("CREATE INDEX useragent ON test_buf (useragent(89))");
mysql_query("CREATE INDEX ip ON test_buf (ip(18))");
|
| |
|
|
|
|
|
|
|
для: Владимир55
(18.05.2009 в 21:02)
| | да. | |
|
|
|
|
|
|
|
для: Владимир55
(18.05.2009 в 17:25)
| | скорее имелось виду, что надо отдельно дать индексы на эти поля, Вы же давали одновременно. тем самым индекс работал только на IP и IP+useragent. отдельно по useragent индекс не работал бы. | |
|
|
|
|
|
|
|
для: а-я
(18.05.2009 в 19:30)
| | "надо отдельно дать индексы на эти поля, Вы же давали одновременно"
Я этого не понимаю.
Не могли бы Вы на моем примере показать, как же это делается? | |
|
|
|
|
|
|
|
для: Владимир55
(18.05.2009 в 20:59)
| | так... если я не ошибаюсь, то примерно так:
первый Ваш вариант:
CREATE INDEX test_buf ON ip, useragent (useragent(99))
-
CREATE INDEX название_ключа ON таблица(поле1,поле2...)
|
Вы хотели в разных таблицах поставить 1 ключ. немного перепутали..
----
почему делать отдельные ключи?
даже, если Вы сделали бы один ключ
CREATE INDEX IP_useragent ON test_buf (ip, useragent(99))
|
что дало ключ своего рода ассоц. массив:
array(
111.111.111.111 => array(
opera...,
mozilla...,
...
),
222.222.222.222 => array(
opera...,
mozilla...,
...
),
...
)
|
т.е. сначала идет поиск по IP и лишь потом смотрит useragent
но сразу useragent никак не посмотришь.
поэтому для юзерагента данный ключ не работает.
во 2ом же варианте:
mysql_query("CREATE INDEX useragent ON test_buf (useragent(89))");
mysql_query("CREATE INDEX ip ON test_buf (ip(18))");
|
здесь создаете отдельно ключи.
//ключ для IP
array(
111.111.111.111,
222.222.222.222
...
)
//ключ для юзерагент
array(
opera...,
mozilla...,
...
)
|
ключи независимы. и можете обратиться как к 1ому так и ко 2ому.. и даж одновременно. | |
|
|
|
|
|
|
|
для: а-я
(18.05.2009 в 22:49)
| | Я строил код в соответствии с указанием cheops (18.05.2009 в 13:32) .
после CREATE INDEX идет название индекса, а после ON - название таблицы. В скобках, через запятую идут названия столбцов по которым создается индекс
Как я писал в самом начале, таблица имет имя test_buf, а поля имеют имена IP и useragent. Вот и получилось:
mysql_query("CREATE INDEX useragent ON test_buf (useragent(89))");
mysql_query("CREATE INDEX ip ON test_buf (ip(18))");
|
Здесь в первом случае индексируется поле useragent, а во втором поле IP таблицы test_buf.
Разве неверно? | |
|
|
|
|
|
|
|
для: Владимир55
(18.05.2009 в 23:12)
| | все у Вас верно.
просто Вы:
А после второго запуска получаю сообщение:
1061 98 : Duplicate key name 'useragent'
1061 98 : Duplicate key name 'ip'
|
т.е. Вы хотите еще раз создать такие же ключи. Этого уже не надо! они уже существуют. | |
|
|
|