Let's say Table T has columns A, B, C, D, E, F, G. and we have primary index as [A, B, C].
Table T has 100k records with value of A as x.
Could you please explain how below query will acquire lock - as in lock on all the rows with value of A=x? and which type of lock.
DELETE FROM T WHERE A=x LIMIT 100;
Related
Given a table with columns a, b and c. Assume an index is created on columns a and b, how will MYSQL execute a query with a WHERE clause using criteria a, b and c.
Additional notes: Will MYSQL use an Index Range Scan in this scenario or do a full table scan for column c?
MySQL uses the index on (a, b) to reduce the examined rows to the set matching your conditions on those two columns.
Then that set of examined rows are evaluated one by one for the other condition on column c. It doesn't do a full table scan, but it does evaluate all of the examined rows.
You can get an estimate of the examined row count from the rows field of the EXPLAIN report.
I am using MySQL as my RDBMS.
But I think it must be applicable to other relational DBs.
I have a table Z, where I have 5 columns: a, b, c, d, e.
Columns a, b, c comprise a composite primary key.
Now, when it comes down to querying in the WHERE clause there will be times when I will be fetching data based on the values of columns a, b, c. But only one column out of 3 will be set.
Do I need to create 3 indices against these columns?
Follow-up question: what if I need to query my table knowing values for 2 columns out of 3? Will the creation of an additional 3 indices help to speed up my queries? (a, b) (a, c) (b, c)
Please advise.
...will be fetching data based on the values of columns a, b, c. But only one column out of 3 will be set.
If that's the case you'll need three indexes:
If a is set your primary key index (a, b, c) will suffice. You don't need to create an extra index for this case.
If b is set you'll need the index (b) for this query to be fast.
If c is set you'll need the index (c) for this query to be fast.
The index (a, b, c) is not useful when a is null. Remember, null is not a value.
Short answer: yes.
INDEX (a, b, c)
-- creates 1 index of unique combinations of a&b&c, not unlike CONCAT(a, b,c)
INDEX (a),
INDEX (b),
INDEX (c)
-- creates 3 indexes of unique values for all a, b, c separately
INDEX (a, b),
INDEX (c)
-- creates 2 indexes:
-- 1st for a&b unique values
-- 2nd for c unique values
Follow up: with WHERE a = '...' AND b = '...', searching thru INDEX(a, b) will be faster than searching thru INDEX(a), INDEX(b). However, if a or b values are (at least mostly) unique, performance increase will not be significant.
When debugging index performance, always start witch checking your indexes' cardinality and later your queries' index usage with EXPLAIN SELECT.
I have some doubts about MYSQL multiple composite indexes with ranges.
For example, if i have the following index:
Multiple column index in columns (A, B, C)
And the following query
WHERE A=2 AND B>5 AND C=3
Question:
- The index will use the columns (A,B,C) or only (A, B)
And what about this one:
WHERE A=2 AND B IN (1,2,3) AND C=4
Thanks!
Question: - The index will use the columns (A,B,C) or only (A, B)
Most likely (A, B). Indexes are positional, so they can't access the next column if the previous one is not using equality. But depending on table stats a full table scan may be faster.
WHERE A=2 AND B IN (1,2,3) AND C=4
Maybe:
only (A), or
(A, B) three times,
or none of them by doing a full table scan.
Statistics will decidedly make a big difference. In essence, is A very selective or not? If not, then a full table scan may be faster than using the index.
Let's assume we have a table with 4 columns: A, B, C, and D
Let's assume we have a few queries that will join or perform a clause against these columns:
Q1: Where A = ?
Q2: Where A = ?, B = ?
Q3: Where A = ?, B = ?, C = ?
Since we know we will use these columns in three different contexts, is it best to create three different indexes? Or three different multiple indexes?
Index Merge:
Idx1: Create index A_idx ON table (A)
Idx2: Create index B_idx ON table (B)
Idx3: Create index C_idx ON table (C)
Multiple Index
Idx1: Create index A_idx ON table(A)
Idx2: Create index AB_idx ON table(A,B)
Idx3: Create index ABC_idx ON table(A,B,C)
This is a simplified case. Let's assume we have 10-15 columns, that will be joined or where'd in different ways and combinations. Is it best to create multiple column indexes for these combinations they will receive? Or just find the smallest set of multiple columns that are most frequently used, build a multiple column index on those, and then create individual indexes for the rest?
Composite index on (A,B,C) will cover the 3 queries, so you don't need index on (A) and ON (A,B). It's also faster than index_merge.
The only reason to have more than one index is if some queries won't be covered by the index (they include B and C, but not A for example)
Also keep in mind that one of the most important characteristics of the column, to decide if it should be included in the index, is not if it's used in a query, but it's cardinality. If the query on this column won't exclude a lot of the rows, you should not include it in the index.
Let's say you have A,B,C
For a given value of A you have 20% of the rows. From those rows, for a given value of B you have 1% of the rows. Lets say those conditions (A,B) filter 1000 rows from the table. After applying C, you receive 850 rows. Index on C is not effective and (A,B) is the best index for this query
I need to merge two MySql databases.
DBtwo is a copy of DBone.
I added data to a table_x in DBone, and I added datas to a table_y in DBtwo.
I need to keep data added in DBOne, while merging all other edits –such as deleted entries- made in DBTwo.
Schemas, then, are identical, while each DB have different data from different tables.
Thank you all for your help.
Edit:
I was forgetting. I added columns to table_x that are foreign keys to table_y. So DBone has some entries that have been inserted without columns I added to table_x in DBtwo. :/
Do you have a copy of the original database before the merge? If not, what you are asking is impossible. Here is the problem:
The original database has these records:
{a, b, c}
In table_x, you add a d, so now you have:
{a, b, c, d}
In table y, you remove a b, so you have:
{a, c}
You now attempt to merge these two data sets:
{a, b, c, d}
{a, c}
Without reference to the original, how do you know whether b and d should be in the new set. If they weren't in the original and you added them since the fork, they should be included. If they were in the original and you deleted them in table_y since the merge, they should not be included.
Assuming you do have access, you'll want to do something like:
insert into table_y
select *
from table_x x
where x.id not in (select id from table_x_original)
And then rename table_y to table_x (if you want table_x to be the new data source). If your ids are generated and you may have conflicts, you'll want to replace the * with a list of all the columns other than the id column to generate a new sequential id.
You could use a trigger. Please see the MySQL documentation for your implementation regarding, triggers, functions and procedures.