ROW_FORMAT = fixed хорошо или плохо?

camel

Новичок
ROW_FORMAT = fixed хорошо или плохо?

Долго анализируя структуру базы Invision Forum столкнулся с тем что почти все таблички dynamic, стал смотреть что можно перевести на fixed.

Сразу встал вопрос что лучше для таблички в которой коло 100-1000 записей и имеющей пару-тройку полей с varchar(100 - 255) быть fixed или же быть dynamic, с одной стороны мануал говорит что типа fixed круто, но при среднем размере строки 40-100 размер таблички увеличивается в два а то и три раза, соответственно что лучше иметь больший файл базы и fixed или меньший размер и dynamic ???

И еще вопрос в догонку кто нить юзал мердж(и еже с ним union и raid) таблицы и есть ли с ними подводные камни? Просто есть табличка и я думаю что скоро с ней будет тяжело, т.к. строк в ней 311871 и средняя строка 708.... Вот и думаю может перевести это дело на merge или что то подобное(может даже самописное).
 

ForJest

- свежая кровь
camel
На твой вопрос нельзя дать однозначного ответа.
Преимущества fixed изложены в мане.
Так как ты собираешься сделать - просто перевести в char(100) - char(255) "просто так" делать не стоит.

-~{}~ 11.01.05 19:17:

Реально же какой-то дельный совет можно дать лишь зная возникшие проблемы или зачем ты вообще решил заняться изменением форматов :)
 

camel

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

Другие таблички это таблицы категорий к которым обрашение происходит на каждой странице и не смотря на то что там всего 1000 записей, время запроса остаетавляет желает лучшего( т.к. идет полный проход ).
 

ForJest

- свежая кровь
camel
Может быть стоит создать индексы? :) Чтобы не было полного прохода :)
 

camel

Новичок
Полный проход идет, т.к. нужны все записи.

mysql> explain SELECT c.* FROM ibf_gallery_categories c ORDER BY c_order ASC;
+-------+------+---------------+------+---------+------+------+----------------+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+-------+------+---------------+------+---------+------+------+----------------+
| c | ALL | NULL | NULL | NULL | NULL | 973 | Using filesort |
+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)

Как видишь тут индексы не помогут
 

ForJest

- свежая кровь
> Using filesort
Рекомендую почитать всё-таки документацию к EXPLAIN, а также перечиать вопросы касающиеся оптимизации в MySQL.
Очень познавательно.
Индексы помогут. Но для этого нужно правильно их использовать :).
На Details есть вроде бы статьи посвящённые этому вопросу :).
Это довольно обширный материал.
Для справки:у самого MySQL есть саппорт. И заплатив смешную сумму ты сможешь плучать рекомендации и советы на каждый свой частный случай не изучая мануал.
 

camel

Новичок
кхе кхе...
скажи мне пожалуйсто как могут помочь индексы сортировке?

допустим ALTER TABLE ibf_gallery_categories ORDER BY c_order ASC;
децл поможет но это дело разово т.е. при изменени любых данных надо делать опять сортировку таблицы но это опять таки не помогает.

Не смотря на то что написано в мануале индекс не цепляется.

Indexes are used to:
Sort or group a table if the sorting or grouping is done on a leftmost prefix of a usable key (for example, ORDER BY key_part_1,key_part_2 ). The key is read in reverse order if all key parts are followed by DESC. The index can also be used even if the ORDER BY doesn't match the index exactly, as long as all the unused index parts and all the extra are ORDER BY columns are constants in the WHERE clause. The following queries will use the index to resolve the ORDER BY part:
SELECT * FROM foo ORDER BY key_part1,key_part2,key_part3;
SELECT * FROM foo WHERE column=constant ORDER BY column, key_part1;
SELECT * FROM foo WHERE key_part1=const GROUP BY key_part2;
далее эксплейн я читал, не маленький букварь знаю

Если ты про статью оптимизация запросов в детейле то там ни слова нет про сортировки и индексы.

Далее что значит правильно использовать? я что-то не наблюдаю в CREATE indeX хороших опций. Далее если ты про USE INDEX то не канает, проход идет все равно полный.

для понятности приведу describe и show index :

mysql> describe ibf_gallery_categories;
+------------------+---------------------+------+-----+--------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+---------------------+------+-----+--------------+----------------+
| id | int(10) unsigned | | PRI | NULL | auto_increment |
| parent | int(10) unsigned | | MUL | 0 | |
| name | char(60) | | | | |
| description | char(100) | YES | | NULL | |
| c_order | int(10) unsigned | | MUL | 0 | |
| images | bigint(10) unsigned | | | 0 | |
| comments | bigint(10) unsigned | | | 0 | |
| perms_view | char(120) | | | | |
| perms_images | char(120) | | | | |
| perms_comments | char(120) | | | | |
| perms_moderate | char(120) | | | | |
| allow_ibfcode | tinyint(1) unsigned | | | 1 | |
| allow_html | tinyint(1) unsigned | | | 0 | |
| password | char(60) | | | | |
| approve_images | tinyint(1) unsigned | | | 0 | |
| imgs_per_col | int(5) unsigned | | | 4 | |
| imgs_per_row | int(5) unsigned | | | 5 | |
| watermark_images | tinyint(1) unsigned | | | 0 | |
| thumbnail | tinyint(1) unsigned | | | 1 | |
| allow_comments | tinyint(1) unsigned | | | 1 | |
| approve_comments | tinyint(1) unsigned | | | 0 | |
| inc_post_count | tinyint(1) unsigned | | | 1 | |
| status | tinyint(1) unsigned | | | 1 | |
| last_pic | bigint(10) unsigned | | | 0 | |
| def_view | char(30) | YES | | date:DESC:30 | |
+------------------+---------------------+------+-----+--------------+----------------+
25 rows in set (0.02 sec)

mysql> show index from ibf_gallery_categories;
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
| ibf_gallery_categories | 0 | PRIMARY | 1 | id | A | 973 | NULL | NULL | | BTREE | |
| ibf_gallery_categories | 1 | parent | 1 | parent | A | 24 | NULL | NULL | | BTREE | |
| ibf_gallery_categories | 1 | c_order | 1 | c_order | A | 973 | NULL | NULL | | BTREE | |
3 rows in set (0.00 sec)

mysql> explain SELECT c.* FROM ibf_gallery_categories c ORDER BY c_order ASC;
+-------+------+---------------+------+---------+------+------+----------------+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+-------+------+---------------+------+---------+------+------+----------------+
| c | ALL | NULL | NULL | NULL | NULL | 973 | Using filesort |
+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)


Я жуе перевел эту табличку в fixed про этому char. Практика показала что при больших нагрузках fixed на данной табличке действительно дает увеличение производительности в среднем случае в худшем же результат такой же как в dynamic.

Если подскажешь как заставить запрос юзать индекс я буду очень признателен пока ни чего дельного я не нашел.
 

ForJest

- свежая кровь
Проход будет в любом случае полный, т.к. у тебя выбираются все записи.
Твоя задача убрать
Using filesort, используя для сортировки индекс.

Вообще индекс на поле у тебя уже есть, насколько я вижу. Попробуй ещё сделай ANALIZE TABLE и OPTIMIZE TABLE.

Какая версия MySQL? Может быть дело в настройках. В этой ситуации муська должна использовать индекс. И по документации и по моему опыту :)
 

camel

Новичок
хм... вообещмто аналайз и оптимайз просто проверяют и делают дефрагментацию таблицы и на оптимизацию запроса по большому случаю не влияют (кроме повреждения таблицы или ключей таблицы ) см. букварь. Дефрагментировать в табличке явно не чего т.к. она fixed. То что она не повреждена это я проверил все путем.

Версию
-bash-2.05b$ mysql --version
mysql Ver 11.18 Distrib 3.23.58, for portbld-freebsd4.9 (i386)
на 4.0.1 та же фигня

Подумал что типа Мускл как оракл не умеет NULL понимать введение NOT NULL на поле тоже не помогло....

То что будет ALL это ес-но ни куда от этого не денешься.
Возникает вопрос а вообще Мускл умеет юзать индексы при сортировке...

USE INDEX тот же результат.
 

f1

formula 1
при сортировке индексы Мускл умеет юзать, это однозначно

проблемы с индексами при сортировке, только если есть одновременное использование ASC и DESС (т.е. ORDER BY pole1 ASC, Pole2 DESC)
 

ForJest

- свежая кровь
camel
Он умеет не волнуйся :). Просто не выполняется набор каких-то условий. На табличке с 3000 записей, формат dynamic используются аж шуршит.
Analyse and store the key distribution for the table
У меня как-то была схожая проблема - MySQL не пользовал индексы, которые должен был пользовать. ANALIZE TABLE решил эту проблему. Я так понимаю он оптимизирует дерево индексов как раз. Вообще если у тебя там после долгих ALTER TABLE ORDER BY табличка, то возможно MySQL решает что ей лучше filesort на этом количестве данных использовать.
 

camel

Новичок
Введение фиктивного условия аля c_order > -1 тоже результат не дает.
Хотя по идее там и сортировать не чего если идти по ключу и просто брать все что больше нуля.... А поиск всех значений начиная с кого то по BTREE индексу задача вообще примитивная.

f1 не наблюдаю в данном случае различной сортировки, даже более того не наблюдаю двух полей


ForJest дык где грабли зарыты?
 

ForJest

- свежая кровь
Хотя да. ANALIZE TABLE это для JOIN's. И проблема у меня была с ними :)

-~{}~ 12.01.05 12:57:

camel
Я не скажу тебе уже где грабли зарыты. Поведение выходит за рамки описанного в документации и опять же за рамки того, с чем сталкивался я.
 

camel

Новичок
mysql> alter table ibf_gallery_categories order by id;
Query OK, 973 rows affected (0.05 sec)
Records: 973 Duplicates: 0 Warnings: 0

mysql> explain SELECT c.* FROM ibf_gallery_categories c ORDER BY c_order;
+-------+------+---------------+------+---------+------+------+----------------+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+-------+------+---------------+------+---------+------+------+----------------+
| c | ALL | NULL | NULL | NULL | NULL | 973 | Using filesort |
+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)


пофигу ей как табличка отсортирована... =)))
 

ForJest

- свежая кровь
camel
Отвлекаясь от темы сортировок с индексами
Вообще если у тебя используются полностью все данные и их немного - почему бы тебе не сделать кэш? Хотя бы для начала в таблице типа HEAP.
Или другие варианты - в memcache или других менеджерах памяти. Опять же примитивный serialize/unserialize.
 

camel

Новичок
1000 строк и каждая строка в среднем около 200-300 байт пробовал по всякому даже писал класс аля кеша в распарсенный php код но тогда думп всего того что фетчуются с извратами становится около 300 Кб и пХп становится плохо от require этого файла...

скорее всего большая часть времени уходит на фетч но как сие оптимизнуть я уже не знаю.
Попросил саппорт поставить мускл 4ый может кеш запросов спасет меня но фиг знает...

что касается Memcache вырублен он на пХп, но это я могу решить в конце концов сервак в аренде и там тока один сайт, просто пол метра в озу это прилично(хотя я мало работал с разделяемой памятью трудно судить что будет плохо или хорошо)....

Serialize около метра будет(уже пробовал не первый день оптимизацией занимаюсь=)))) ).
 

ForJest

- свежая кровь
camel
Пол метра висящие в ОЗУ честно сказать это совсем немного. С учётом того, что каждая копия PHP жрёт памяти не меньше метра, при какой-нибудь серьёзной нагрузке ты не заметишь разницы :)
Но это уже выходит за пределы начального топика :)
 

camel

Новичок
ForJest ок понял спасиб буду делать значит шаремем.

ес-но вопрос с индексом остается открытым
 
Сверху