Using ORDER BY while still maintaining use of index - mysql

I'd like to retrieve some rows utilizing my index on Columns A and B. I was told the only way to ensure my index is being used to retrieve the rows is to use an ORDER by clause, for example:
A B offset
1 5 1
1 4 2
2 5 3
2 4 4
SELECT A,B FROM TableX
WHERE offset > 0 AND offset < 5
ORDER BY A,B ASC
but then I would like my results for just those rows returned to be ordered by column B and not A,B.
A B
1 4
2 4
2 5
1 5
How can I do this and still ensure my index is being used and not a full table scan? If I was to use ORDER BY B then doesn't this mean MySQL will scan by B and defeat the purpose of having the two column index?

Any index that includes A or B cloumns will have no effect on your query, regardless of your ORDER BY. You need an index on offset as that is the field that is being used in hte WHERE clause.

Sorry, but maybe I did not understand the question..
The above output query should result:
A B
1 4
1 5
2 4
2 5
For avoiding table scan, you should add an index for the offset and use it in your WHERE clause.
If possible to use unique then use it.
CREATE UNIQUE INDEX offsetidx ON TableX (offset);
or
CREATE INDEX offsetidx ON TableX (offset);

Considering your query, the best index is probably (offset,A,B). This will allow the optimizer to use the leftmost part of the index to honor the WHERE clause, and the rest of the index allowing to use merge sort.
ALTER TABLE TableX ADD INDEX (offset,A,B);
In order to take full advantage of that, the query has to be rewritten as:
SELECT A,B FROM TableX
WHERE offset BETWEEN 0 AND 5
ORDER BY A,B;
See http://sqlfiddle.com/#!2/c8e718/2

Related

Count 1 column of 2 without condition

I want to count the content of one column, which is no problem.
But also i want to count another column content but with a where condition.
I visualize it for better explaining:
My table
Index1 Index2
1 0
1 2
2 2
2 2
2 2
now i want to count the content of Index1 that i know how often the numbers 1 and 2 appears.
But further i want to count the content of Index2, but only the numbers which are higher than 1.
Result
Index1 amount
1 1
2 3
but when i use the where condition it is used for both columns.
I tried it with distinct but it doesn´t work.
Are there some comfortable solutions for this problem?
That's called conditional aggregation, and in MySQL it's pretty simple :
SELECT t.index1,
COUNT(*) as amount
SUM(t.index2>1) as amountWithWhere
FROM YourTable t
GROUP BY t.index1

How to index every 1000 number together

I have a table with a 'billnumber' column (INT 11)
billnumber value may changed every 3 or 4 records so if I index a 1M record I will have a 250K index
What I want is anyway to index every 1000 billnumber together
- from 1 to 1000
- from 1001 to 2000
Is there actually a problem?
INDEX(billnumber) is non-unique, this will return 3 or 4 rows without difficulty:
SELECT ...
WHERE bill_number = 1234
If you want to select 1..1000, simply do
SELECT ...
WHERE bill_number BETWEEN 1 AND 1000;
Both are efficient.
Keep in mind, a data base table has no order. To get the rows ordered, you must use ORDER BY.
Meanwhile, INDEXes try to make WHERE and ORDER BY efficient.

MySQL limit clause unusal issue

SELECT id,name,info FROM table LIMIT 5
the result Set should be contains 5 rows wich is The first 5 rows of the table,but is any exception about this usage? .the table like this :
SELECT * FROM table limit 10;
1. company_id company_name tel
1 TCL集团股份有限公司 0752-2288333
2 UNITEDSTACK(北京)科技有限公司 15727325616
3 《市政技术》杂志社有限公司 13401070358
4 《网络安全技术与应用》杂志社有限公司 010-62765013
5 《艺术市场》杂志社股份有限公司 64271947
7 一呼医知己健康咨询(北京)有限公司 010-62957992
8 一呼(北京)电子商务有限公司 62957992
9 一汽轿车股份有限公司 0431-85782608
10 一通万通商务服务(北京)有限公司 010-68061805
I use the first sql the result is normal:like this
SELECT company_id,company_name,tel FROM table LIMIT 5;
1. 1 TCL集团股份有限公司 0752-2288333
2 UNITEDSTACK(北京)科技有限公司 15727325616
3 《市政技术》杂志社有限公司 13401070358
4 《网络安全技术与应用》杂志社有限公司 010-62765013
5 《艺术市场》杂志社股份有限公司 64271947
However I use the second sql like this :
SELECT comapny_id,company_name FROM table LIMIT 5;
1275992
1758051
2990914
5241776
5344925
We are seeing the result is not the 5 rows of the table obviously,the difference of these fileds is that company_id is a primary key,company_name is a type of MUL.can you help me?thank you very much!
the result Set should be contains 5 rows wich is The first 5 rows of
the table,but is any exception about this usage?
Only the first part of this statement is correct. Your query returns 5 rows from the query. However, those are 5 indeterminate rows.
SQL tables represent unordered sets. Hence, there is no first five rows in a table. If you want your result set ordered, then you need to include an order by clause. Often, an auto-incremented id is used for this purpose, because such an id captures the order that rows are inserted into the table.

Is MySQL's `ORDER BY` distinct on multisets?

Assuming a table with a column where integers are stored.
-----------------------------
id | some_int | some_other_value
-----------------------------
1 5 hello
2 9 how
3 987 are
4 5 you
5 9 thanks
6 1 for
7 5 answering. :-)
Is SELECT * FROM mytable ORDER BY some_int; distinct? Meaning will it always return the rows in the same order, after each query?
To the best of my knowledge if there are duplicates in the order by clause, there is no guarantee for the order in which the duplicates are presented.
If this is a concern, you could modify the order by to include the primary key (id I am assuming).
ORDER BY some_int, id
Since id is a primary key, it should also be indexed. Thus the performance difference will be minimal.
Doing this order by does not always have to give you the same result order. It is not frequent that the order will be different but it's not a 100% safe to assume that the order will always be the same as it is not an unique value that you're ordering by. To achieve this you should also include the primary key after the initial order.
SELECT * FROM mytable ORDER BY some_int, id
Use this:
SELECT * FROM mytable ORDER BY some_int,id;
So it will sort for 'some_int' and then using 'id' Duplicates for 'some_id' will be set to fixed position using 'id' column

mySQL - return best results

I want to have a query that returns the best results from a table.
I am defining the best results to be the addition of two columns a + b (each column holds an int)
ie:
entry a b
1 4 5
2 3 2
3 20 30
Entry 3 would be returned because a + b is the highest in this case.
Is there a way to do this? One idea I had was to create another column in the table which holds the addition of a and b and then ORDER by DESC, but that seems a little bit messy.
Any ideas?
Thanks!
SELECT *
FROM mytable
ORDER BY
a + b DESC
LIMIT 1
Adding another column, however, would be a good option, since you could index this column which would improve the query.