MySQL - Change index on myIsam table - mysql

I have a table where two columns are used in a where condition.
This is a MyIsam table and both columns hold text and use FULLTEXT as index.
The values in both columns are not unique.
The select statement works pretty slow.
Question is: can I simply remove the FULLTEXT index and use another index instead?
The query that is used is just as simple as possbile:
SELECT * FROM tbl WHERE col1=X AND col2=y and col3=z
Thanks!

ALTER TABLE `tableName` DROP INDEX `indexName` ,
ADD INDEX `indexName` ( `ColName` )
This shuld remove the old "FULLTEXT" index and add a "NOT FULTEXT" index.

Related

MySQL Alter Full Text Search Columns

Ok, so I've full text index on one table for col1 and col2 for example. I want to change this to only have col1 included in the full text index. How to do this?
You can not ALTER INDEX in MySQL, you need to DROP INDEX and CREATE INDEX a new one
Firstly, identify the name of your Full Text Index using the following MySQL query;
SHOW CREATE TABLE your_table_name;
Then run the following MySQL query to drop the table;
ALTER TABLE your_table_name DROP INDEX name_of_index_identified_by_previous_query_above;
Then create your Full Text Index again using the following code;
ALTER TABLE your_table_name ADD FULLTEXT INDEX `FullText` ('col1', 'col2', 'col3', 'etc');

MySQL index for ORDER BY A*B

I have a MySQL InnoDB table with two INT columns, say col1 and col2. I'd like to add an index that will allow me to:
SELECT * from myTable WHERE col0=5 ORDER BY col1*col2 DESC
Is it possible to have an index that will support such a sorting or will i need to add a column that keeps that value (col1*col2) ?
Noam, see ORDER BY Optimization‌​. If you want to use the index for sorting, it should be the same as the index, that is used in the WHERE clause and of course the value for sorting needs to be stored in it's own column. Here I generated a test table with 100k rows, that should match your situation.
1.) Adding ONE INDEX on two columns (this works for utlizing an index for both select and sort):
ALTER TABLE `test_data` ADD INDEX super_sort (`col0`,`sort_col`);
EXPLAIN SELECT * FROM `test_data` WHERE col0 = 50 ORDER BY sort_col;
key -> super_sort; Extra -> using where
(index is used for WHERE and SORT)
2.) Adding two indexes, one for WHERE and one for SORT (won't work)
ALTER TABLE `test_data` DROP INDEX `super_sort`;
ALTER TABLE `test_data` ADD INDEX (`col0`);
ALTER TABLE `test_data` ADD INDEX (`sort_col`);
EXPLAIN SELECT * FROM `test_data` WHERE col0 = 50 ORDER BY sort_col;
key -> col0; Extra -> Using where; Using filesort
(an index is used for WHERE, BUT NOT for sorting)
So the answer is: Yes, you will need a column, that keeps that value (col1*col2) AND you need ONE index on both columns: col0 (for the WHERE-clause) + sort_col (for sorting) like in first example. As soon, as you ORDER BY any calculation (e.g. col1*col2) no index can be used for sorting.
You can add new column that contains the value of col1*col2 and use it for sorting. Otherwise you can use SELECT * from myTable WHERE col0=5 ORDER BY col1*col2 DESC.

Mysql multiple columns index

UPDATE album SET x=1 WHERE store_id=:store_id && type=:type && time<:time
I have a Mysql update query, My question is how can I set up the index for this query
I create index in phpMyadmin, should I select store_id, type, time together and create one index?
if you are searching by store_id and type and time together then yes you can create INDEX for those three.
BUT,
if sometimes you are searching only by store_id then here you should use index only in store_id
if you search by store_id and type then index will be on those two columns.
so it depeneds what are columns you using to search.
here how to use to create what index you want.
ALTER TABLE `album` ADD INDEX `myindex` (`store_id`) --for store_id
ALTER TABLE `album` ADD INDEX `myindex` (`store_id` ,`type`,`time`) --for store_id and type and time
and so on ....
choose which one you want.
When setting up an index, the place to start is the where clause:
WHERE store_id=:store_id && type=:type && time<:time
Start with the equality comparisons. Then you can choose one column for inequality. For this query, the best index would have all three columns:
create index album_storeid_type_time on album(store_id, type, time);

Indexing mysql query

I have this query in mysql and I wanted to be indexed, what is the best index composition?
SELECT cometchat.id, cometchat.from, cometchat.to, cometchat.message, cometchat.sent, cometchat.read, cometchat.direction
FROM cometchat
WHERE (
(
cometchat.to = '30411'
AND cometchat.direction <>2
)
OR (
cometchat.from = '30411'
AND cometchat.direction <>1
)
)
I've tried these indexes but they didn't work:
ALTER TABLE `cometchat` ADD INDEX ( `from`,`to`,`direction`)
ALTER TABLE `cometchat` ADD INDEX ( `from`,`to`)
ALTER TABLE `cometchat` ADD INDEX ( `to`,`direction`)
ALTER TABLE `cometchat` ADD INDEX ( `from`,`direction`)
Any help would be much appreciated.
Because of the OR in your where clause, you'd need 2 separate indexes to optimaze selects:
ALTER TABLE `cometchat` ADD INDEX index1 ( `to`,`direction`)
ALTER TABLE `cometchat` ADD INDEX index2 ( `from`,`direction`)
I wouldn't bother trying to make these covering indexes--just eat the cost of the point lookup. However, if you want them to be covering you'd need:
ALTER TABLE `cometchat` ADD INDEX index1
( `to`,`direction`, `message`, `sent`, `read` );
ALTER TABLE `cometchat` ADD INDEX index2
( `from`,`direction`,`message`, `sent`, `read`);
The covering indexes will give best select performance, but it's a lot of extra storage and will add to insert overhead--so I'd only use them if performance with the non-covering ones are inadequate and this is a insert light table.
Also, just some general advice, I'd avoid using MySQL reserved words like 'from' when naming databases, tables, or columns. https://dev.mysql.com/doc/refman/5.5/en/reserved-words.html
When you use a reserved as a name for something you're really asking to run into a buggy query that will result in another SP question ;)
Try using only the following:
ALTER TABLE `cometchat` ADD INDEX (`direction`)

have 3 FULLTEXT indexes on same table.. how to merge them?

on my table I have 3 different FULLTEXT indexes like so:
FULLTEXT KEY `product_name` (`product_name`,`product_description`),
FULLTEXT KEY `product_brand` (`product_brand`,`metal_type`,`primary_stone`,`product_type`,`product_type_sub`,`product_series`),
FULLTEXT KEY `primary_stone_sub` (`primary_stone_sub`)
This is because I added them after the fact like so:
ALTER TABLE cart_product ADD FULLTEXT(columnA, columnB);
Q1 How can I merge these 3 into 1 FULLTEXT index?
Q2 Also, so this doesn't happen again, how would I add a FULLTEXT column to the already existing FULLTEXT index?
Thanks!!!
It seems like you only want to have 1 FULLTEXT index, containing all of those columns. Is that right? You can also have several FULLTEXT indexes on this table, one containing all of the columns and others containing a subset. It all depends on your usage.
Just remember this caveat from the manual and make sure your fulltext index column list(s) match the columns you are querying against exactly:
The MATCH() column list must match exactly the column list in some FULLTEXT index definition for the table, unless this MATCH() is IN BOOLEAN MODE. Boolean-mode searches can be done on nonindexed columns, although they are likely to be slow.
The answer to both questions is that you need to drop the existing index and recreate it with an updated list of columns:
ALTER TABLE cart_product
DROP INDEX `product_name`,
DROP INDEX `product_brand`,
DROP INDEX `primary_stone_sub`,
ADD FULLTEXT INDEX `cart_product_fti` (
`product_name`,
`product_description`,
`product_brand`,
`metal_type`,
`primary_stone`,
`product_type`,
`product_type_sub`,
`product_series`,
`primary_stone_sub`
);