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.
Related
select * from "Test"."EMP"
id
1
2
3
4
5
Select SUM(1) FROM "Test"."EMP";
Select SUM(2) FROM "Test"."EMP";
Select SUM(3) FROM "Test"."EMP";
why the output of these queries is?
5
10
15
And
I don't understand why they write table name like this "Test"."EMP"
your table has 5 records. the statement select 1 from test.emp returns 5 records with values as 1 for all 5 records.
id
1
1
1
1
1
This is because db engine simply returns 1 for each existing record without reading the contents of the cell. and same happens for select <any static value> from test.emp
same happens for 2 and 3
id
2
2
2
2
2
hence there are 5 records returned with the static values and sum of those values will be the product of static number passed in the select statement and total records in the table
additional fact: It is always recommended to perform count(1) than count(*) as it consumes less resource and hence less load on the server
I don't think it's "Test"."EMP" with double quotes.. it's probably `Test`.`EMP` with backticks instead. The definition means its database_name.table_name. This is the recommended format to get the correct table_name from database_name; in this case, you're specifically making the syntax to query from `Test`.`EMP`. Read more about identifier qualifiers.
As for SUM(x), the x get's repeated according to the rows present in the table. So SUM(1) on 5 rows is 1+1+1+1+1, SUM(2) on 5 rows is 2+2+2+2+2, and so on.
We have following table with columns:
CategoryId | CategoryName with CategoryId as primary-key.
We have following data:
0 Other
1 Bumper
2 Door
3 Roof
4 Fender
I use select * from these table and i get rows in the above sequence only i.e. 0 first and 4 at last.
Is there any way I can get 0 at last? i.e. 1,2,3,4,0?
select * from yourtable order by CategoryId=0,CategoryId
You can use arbitrary expressions in an order by clause. By first ordering by CategoryId=0, you get all records for which that is false, followed by records (obviously only one, since it is the primary key) for which it is true. Then each of those sets of records are sorted by CategoryId.
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.
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
I have a query that is using ORDER BY RAND() but it takes too long and it's getting worse as data is growing.
The query joins two tables and it returns 5 random products and a random image of each product
Table 1 - Products
product_id - pk auto-inc
name
description
Data
1 - product 1 - description
2 - product 2 - description
Table 2 - ProductImages
image_id - pk auto-inc
product_id - fk index
filename
Data
1 - 1 - product 1 image
2 - 1 - product 1 image
3 - 1 - product 1 image
4 - 2 - product 2 image
...
I've read this and this but cannot find a way to optimize the query so i'm asking for help.
Thanks in advance.
ORDER BY RAND() is slow because the DBMS has to read all rows, sort them all, just to keep only a few rows. So the performance of this query heavily depends on the number of rows in the table, and decreases as the number of rows increase.
There is no way to optimize that.
There are alternatives, however:
You can implement "get 5 random rows" by doing 6 queries:
get number of rows in table (you can cache this one)
do 5 queries with OFFSET <random offset from 0 to $number_of_rows-1> LIMIT 1 (i.e. read and return only one row from some random offset)
For example: SELECT * FROM Products OFFSET 42 LIMIT 1 (note: without joining, for now)
Such queries are very fast and run in a time virtually independent from the table size.
This should be much faster than ORDER BY RAND().
Now, to get a random Image for each random Product:
SELECT *
FROM (
SELECT *
FROM Products
OFFSET 42 LIMIT 1
) p
JOIN ProductImages pi
ON pi.product_id = p.id
ORDER BY RAND()
LIMIT 1
The inner query is still fast, and the outer is only sorting few rows (assuming there are few images per product), and so can still use order by rand().