Create functions indexes MySQL - mysql

I have a table with [date] index.
[date] column:
'2015-01-05'
'2015-01-06'
and etc
Can I create new index for function index?
When i am trying to create it I get error, example:
create index date_y on table (year(date))
If I could we didn't recreate queries for program performance.

Yes and no. No, you cannot create an index on an expression in this fashion. However, if you happen to have mysql v5.7.8 or newer, then you can create generated columns and you can create a secondary index on them (secondary index means that a generated column cannot be part of a primary key).
So, create your expression as a generated column and then create an index on it - if you have mysql v5.7.8 or newer.

One moment, when I have:
date is created index on tableX
id is created index on tableX
id is created index on tableY
My query:
Select * from tableX as x left outer join tableY as y on x.id=y.id
where year(x.date)=2015 and month(x.date)=11
Should I recreate date to:
create index date on tableX (date,id)
or some else?

Related

MySql/MariaDB: Using Indexes in queries "directly"?

I wonder if there is a possibility in MySql/MariaDB to make use of an index in a query directly. Suppose we have a simple unsorted table with timestamp/value-pairs:
CREATE TABLE simple (timestamp DATETIME, val INT);
By adding an index for the timestamp:
ALTER TABLE simple ADD INDEX ind_ts (timestamp);
we have a "fast access" to a kind of sort order of the timestamps.
Let's define a query that delivers the difference of values of consecutive values:
SELECT
c.timestamp AS currenttimestamp,
COALESCE(b.timestamp,'0000-00-00 00:00:00') AS timestampbefore,
c.val - COALESCE(b.val,0) AS difference
FROM simple c,
simple b
WHERE b.timestamp = (SELECT MAX(timestamp) FROM simple h WHERE h.timestamp < c.timestamp)
It is obvious that this query is circumstantial and expensive. A more convient way would be adding a column myindex to the table:
ALTER TABLE simple ADD COLUMN (myindex INT) AFTER timestamp;
and fill the new column with the chronical order of timestamp (e.g. by some php-code)
The new query would be simpler and less expensive:
SELECT
c.timestamp AS currenttimestamp,
COALESCE(b.timestamp,'0000-00-00 00:00:00') AS timestampbefore,
c.val - COALESCE(b.val,0) AS difference
FROM simple c
LEFT JOIN simple b ON c.myindex = b.myindex+1
The new column myindex is somehow similar to the database's table index ind_ts. (Why) is there no MySql construct to use ind_ts instead of myindex?
If you are using MySQL 8.0 or MariaDB 10.2 (or later), LEAD() and LAG() provide a simple way to see the row before or after.
If you are using an older version, then do a "self join". That is, JOIN the table to itself. Then line up the two "tables" offset by one. This may require generating a temp table with a fresh AUTO_INCREMENT to provide an easy way to do the offset. This may be slightly better than your idea about "myindex".
CREATE TABLE new_table (
myindex INT UNSIGNED AUTO_INCREMENT,
PRIMARY KEY(myindex))
SELECT * FROM simple;
Then
SELECT a.ts - b.ts AS diff -- (or whatever the math is)
FROM new_table AS a
JOIN new_table AS b ON a.myindex = b.myindex - 1
(This does not take care of the first and last rows of the table.)
Note: You cannot use a TEMPORARY TABLE since such cannot be JOINed to itself.

using ifnull with index creation in mysql

I am trying to create an index in MySQL whereas the query will first check what column is not null. After checking, it will create the index on the column that is not null. However, I am not successful in creating this and it says I have an error, can someone help me? please see my code below
create index IDX_KSE_NO_01 on tb_kse(ifnull(ss_no, id_no);
#lad2025 is correct that MySQL does not support function-based indexes (like PostgreSQL does), but MySQL 5.7 introduced a feature for virtual generated columns based on expressions, and then you can create an index on a virtual column.
ALTER TABLE tb_kse ADD COLUMN either_no VARCHAR(10) AS (IFNULL(ss_no, id_no));
CREATE INDEX IDX_KSE_NO_01 ON tb_kse(either_no);
MySQL does not support function-based index. You should create normal index:
create index IDX_KSE_NO_01 on tb_kse(ss_no);
create index IDX_KSE_NO_02 on tb_kse(id_no);
And rewrite your query (OR-Expansion):
SELECT *
FROM tb_kse WHERE ss_no = ?
UNION
SELECT *
FROM tb_kse
WHERE ss_no IS NULL AND id_no = ?;
DBFiddle Demo
Another way is to create generated column and create index on top of it:
CREATE TABLE tb_kse(id_no INT, ss_no INT,
gen_col INT GENERATED ALWAYS AS (ifnull(ss_no, id_no)) STORED);
create index IDX_KSE_NO_01 on tb_kse(gen_col);
SELECT *
FROM tb_kse
WHERE gen_col = ?;
DBFiddle Demo 2

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);

How to create an index on a date column

I have a mysql table that has a date column. I have approx 800,000 rows in the table so I want to index. The most common search is going to be:
Select X,Y,Z from table where dateField='yyyy-mm-dd';
the date is in standard mysql yyyy-mm-dd format.
what type of index do i want to create?
CREATE INDEX 2013- ON customer (date(10));
or
CREATE INDEX 201 ON customer (date(10));
or am I way off?
I am new to indexing so any help would be great.
Just add an index on dateField and give it a simple name, such as the column name.
For example:
alter table your_table
add index dateField (dateField);

MySQL - Change index on myIsam table

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.