Making use of index in mysql join - mysql

I have a MySQL table T and there is an index on a column c1. My join query is as follows.
select something from T as t1 inner join T as t2 on ABS(t1.c1-t2.c1)<2;
I used explain to see whether MySQL uses index or not. It didn't use index for the above query. But it did use index for below query.
select something from T as t1 inner join T as t2 on t1.c1=t2.c1;
So how can make MySQL use index on the first query?
Thanks in advance.

You need to remove the function call surrounding the t2.c1 column in order to use the index on that column.
A query like this should work for you:
SELECT something
FROM T AS t1
INNER JOIN T AS t2 ON t2.c1 > (t1.c1 - 2) and t2.c1 < (t1.c1 + 2);
NOTE: This assume that you have an index on the c1 column.

Related

How to delete duplicate data based on two columns

I want to make a query that deletes duplicate data leaving only one duplicate data when two columns overlap.
Maybe because of a lot of data, but the following query doesn't work for a long time
DELETE t1 FROM table t1 INNER JOIN table t2
WHERE t1.idx < t2.idx AND t1.Nm = t2.Nm AND t1.product = t2.product;
Can this query do what I want? If not, what is the other way?
Create an Index on the 3 columns involved in the ON clause:
CREATE INDEX idx_name
ON tablename (Nm, product, idx);
and execute the query like this:
DELETE t1 FROM tablename t1 INNER JOIN tablename t2
WHERE t1.Nm = t2.Nm AND t1.product = t2.product AND t1.idx < t2.idx;
As you can see in this simplified demo, the query will be executed using the index.

how sql engine handle join query with non-equal?

sql engine would use HashJoin if a query like this:
select * from table1 t1 left join table2 t2 on t1.id = t2.id;
that's fine. but if the query is like this:
select * from table1 t1 left join table2 t2 on t1.id > t2.id;
how to handle this?
the nestedloop join would work, but is there any better way?
For distributed SQL, a straight up non-qual join (t1.id > t2.id) is pretty expensive to execute. If one side is small you do a broadcast, and then use a sorted index on every node. If both sides are large, you can to range partition one and build a sorted index, and then replicate the other rows to any range that might match.
Normally, you have a combination equality and non-equal join like t1.id = t2.id and t1.cost < t2.cost. In that case, case you can do a normal distributed hash join, and then keep a sorted list of the secondary items to perform the non-equal part. This is what Presto does.

How do I perform SQL Join equivalent functionality in sphinx?

Can anyone tell me how can we achieve the functionality of SQL join in sphinx search?
I want to index few columns from table1 and few from table2.
Tables are in MySQL.
1° as Barryhunter answer
sql_query = SELECT t1.id,t1...., t2.... FROM table1 AS t1 INNER JOIN table2 AS t2 ON ....
2° if one-to-many
sql_query = SELECT t1.id,t1...., group_concat(t2.foo) ASt 2_foo, . FROM table1 AS t1 INNER JOIN table2 AS t2 ON .... GROUP BY t1.id
group_concat has length limitation but sphinx is marvellous
sql_query = SELECT t1.id,t1....,. FROM table1 AS t1;
sql_joined_field = t2_foo from query;\
SELECT t2.rel_t1_id , t2.foo\
FROM table2` AS t2\
ORDER by t2.rel_t1_id ASC
As my English is poor, read this is probably more clear
http://sphinxsearch.com/docs/current/conf-sql-joined-field.html
sql_joined_field = t2_foo would add one more "searchable" field called t2_foo. In this field you retrieve t2.foo content (like the group concat but seperated by space)
The first column must be the id matching to t1.id in your sql_query
ORDER by theID ASC is mandatory
In same idea you can use mva for multiple value in an attribute
http://sphinxsearch.com/docs/current/conf-sql-attr-multi.html
sql_attr_multi = uint tag from query; \
SELECT id, tag FROM tags
You can just use a join in the sql_query, its just a standard MySQL query, that indexer runs and indexes the output. the MySQL server just needs to run it.
sql_query = SELECT id,t.name,o.test FROM table1 t INNER JOIN other o USING (id)

MySql select by excluding all id from another table

I would like to select data from a table which looks like
ID|FOO|CITY|BAR
there is another table where all data which has been selected yet will be stored so that I get unique results. This table looks like
ID|ID_from_other_table
Now I'm stucking if I either should use a left join or a union?
Which one is faster and, how can I set this up the correct way?
left join would be probably faster in MySQL rather than other anti-join patterns like not in and not exists.
select t1.*
from table1 t1
left join table2 t2 on t1.id = t2.id_from_other_table
where t2.id is null

Left join part of the table

I am trying to join two table using left join, that is table1 left join table2.
I would only like part of the rows from A to be joined with B. Is it recommended that i use a sub query to filter rows from table1 or avoid them in where clause to improve my query performance?
select t1.a
,t1.b
,t2.c
from (select *
from table1
where a='x'
) t1 LEFT JOIN table2 t2 on t1.d=t2.d
or
select t1.a
,t1.b
,t2.c
from table1 t1 LEFT JOIN table2 t2 on t1.d=t2.d
where t1.a='x'
Check the query plan but I doubt it would make any difference.
It very depends on the structure and content of your database. The best way is to look into the query plan and compare it for both versions of your query.
You can find this documentation useful: MySQL Query Execution Plan