Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Непонятки с CREATE INDEX
 
 автор: Владимир55   (18.05.2009 в 13:13)   письмо автору
 
 

Из таблицы 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 ?

  Ответить  
 
 автор: cheops   (18.05.2009 в 13:32)   письмо автору
 
   для: Владимир55   (18.05.2009 в 13:13)
 

Дело в том, что после ключевого слова ON должно идти название таблицы. Один вызов оператора CREATE INDEX - создается один индекс (он может быть и по нескольким столбцам, однако, вам сейчас нужно два индекса - поэтому нужно два оператора CREATE INDEX). Причем после CREATE INDEX идет название индекса (может совпадать с названием столбца), а после ON - название таблицы. В скобках, через запятую идут названия столбцов по которым создается индекс - если столбец один - он просто указывается (это как раз ваш случай и эта часть запроса написана правильно).

  Ответить  
 
 автор: Владимир55   (18.05.2009 в 14:32)   письмо автору
 
   для: 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 для данной таблицы выполняется однократно? Можно и для пустой таблицы?
Или каждый раз перед каждым ресурсоемким поиском для предварительной индексации накопившейся информации?)

  Ответить  
 
 автор: а-я   (18.05.2009 в 16:46)   письмо автору
 
   для: Владимир55   (18.05.2009 в 14:32)
 

а зачем Вам на одно поле 2 раза создавать индексы?

- создал таблицу
- поставил индексы
и все, больше индексы не трогают.

  Ответить  
 
 автор: Владимир55   (18.05.2009 в 17:25)   письмо автору
 
   для: а-я   (18.05.2009 в 16:46)
 

"зачем Вам на одно поле 2 раза создавать индексы?"

cheops писал: "вам сейчас нужно два индекса - поэтому нужно два оператора CREATE INDEX"


- создал таблицу
- поставил индексы


Так все же два оператора или один?

  Ответить  
 
 автор: Root   (18.05.2009 в 17:39)   письмо автору
 
   для: Владимир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

  Ответить  
 
 автор: Владимир55   (18.05.2009 в 21:02)   письмо автору
 
   для: 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))");

  Ответить  
 
 автор: root   (18.05.2009 в 21:24)   письмо автору
 
   для: Владимир55   (18.05.2009 в 21:02)
 

да.

  Ответить  
 
 автор: а-я   (18.05.2009 в 19:30)   письмо автору
 
   для: Владимир55   (18.05.2009 в 17:25)
 

скорее имелось виду, что надо отдельно дать индексы на эти поля, Вы же давали одновременно. тем самым индекс работал только на IP и IP+useragent. отдельно по useragent индекс не работал бы.

  Ответить  
 
 автор: Владимир55   (18.05.2009 в 20:59)   письмо автору
 
   для: а-я   (18.05.2009 в 19:30)
 

"надо отдельно дать индексы на эти поля, Вы же давали одновременно"

Я этого не понимаю.
Не могли бы Вы на моем примере показать, как же это делается?

  Ответить  
 
 автор: а-я   (18.05.2009 в 22:49)   письмо автору
 
   для: Владимир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ому.. и даж одновременно.

  Ответить  
 
 автор: Владимир55   (18.05.2009 в 23:12)   письмо автору
 
   для: а-я   (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.

Разве неверно?

  Ответить  
 
 автор: а-я   (19.05.2009 в 07:16)   письмо автору
 
   для: Владимир55   (18.05.2009 в 23:12)
 

все у Вас верно.
просто Вы:


А после второго запуска получаю сообщение:

1061 98 : Duplicate key name 'useragent' 
1061 98 : Duplicate key name 'ip'


т.е. Вы хотите еще раз создать такие же ключи. Этого уже не надо! они уже существуют.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования