using ifnull with index creation in mysql - 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

Related

Create functions indexes 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?

MySQL predicate pushing

Is there any way to force MySQL to push a predicate into a view?
Example:
CREATE TABLE t1(
id INT(11) NOT NULL AUTO_INCREMENT
PRIMARY KEY (id)
);
CREATE VIEW v1
AS SELECT * FROM t1;
The query below will not use PRIMARY KEY index in MySQL:
SELECT *
FROM v1
WHERE id = 1
Instead it will select everything from t1, create a derived table and then filter it out for id = 1.
Is there any way to overcome this?
PS: my real life example is a little bit more complex than the one above, but for simplicity I used the example above
PPS: here's a related Stack Overflow question: How do I get MySQL to use an INDEX for view query?
Yes but you'd have to switch to the fully-compatible MariaDB 10.2.2
This is on by default and can be switched off using optimizer_switch:
SET GLOBAL optimizer_switch='condition_pushdown_for_derived=off'

select unique row identifier in mysql for updating

in infomix i have seen queries like this
select rowid from table where condition
and for update they use the same row id
update table set field="val" where rowid=rowid
is there anything similar in mysql database
does uuid function does the same in mysql .
actually my problem is, there is no primary key in the table so when porting infomix query to mysql i need to consider all the fields in where condition .
please help if there is an alternate solution ,
why not...
select rowid from table where condition
|
V
update table set field="val" where condition
If you are porting your queries from informix to mysql, why don't you modify your tables to include a primary key?
you could even name the PK rowid to maintain portability between the informix and mysql queries.
ALTER TABLE table
ADD rowid MEDIUMINT NOT NULL AUTO_INCREMENT KEY
you can use same condition for both query which you pass on first query, it returns you unique row..
try this
select rowid from table where condition
and for update use the same condition as above instead of row id
update table set field="val" where rowid=rowid

MySQL perfomance issues in SELECT

A simple database:
CREATE TABLE data (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
code VARCHAR(50),
value VARCHAR(10),
);
There are currently ~2 millions rows.
Query like:
SELECT value FROM data WHERE `code`='12345';
executes for 10-12 seconds.
What the best way to increase performance of simple select queries?
Create an index on the code column:
ALTER TABLE data ADD INDEX (code)
Add index to code. Also, is code always numeric (make it type int) and/or is it unique (make it unique or primary key)?
In some cases you may find that adding an index on the code column does not suffice, so if that doesn't work for you you would need to add a (single) index for both the code and value columns.
You can use EXPLAIN SELECT ... to ask MySQL for information about how it's going to execute your query. This would tell you that it needs to check every row. Improving this is a matter of adding an index on the code column which is used in your WHERE clause.
EXPLAIN
http://dev.mysql.com/doc/refman/5.0/en/explain-output.html
CREATE INDEX
http://dev.mysql.com/doc/refman/5.0/en/create-index.html

CREATE INDEX with condition?

I am using MySQL v5.1.
I would like to create index on a table by executing the following SQL statement:
CREATE INDEX index_name
ON table_name (column_name)
But, I wan to firstly check if the index on that column has already been created or not, if not, create it (otherwise do not create). What is the SQL syntax for this?
Mysql doesn't have IF NOT EXISTS for CREATE INDEX. You can work it out by querying information_schema.statistics table. Take a look here, there is an example of stored procedure that does what you are looking for (search for "CREATE INDEX IF NOT EXISTS" on the page)
You want SHOW INDEX.
To get all the indexes on a table:
SHOW INDEX FROM table_name
MySQL allows you to add a WHERE clause to limit the results as well.
Lock the table while you're checking to see if the index exists (and if it doesn't exist, creating the index) so that another process doesn't create the index right after you've checked for it but before you've created it yourself.