MySQL InnoDB table with a Hash Index - mysql

I have a table like this.
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
Later i have created a HASH index like this.
CREATE INDEX index ON table (column) USING HASH;
Latter i have try some explain queries.
Like
explain Select * from table where column=132;
And i see the engine is using the index on possible_keys and in the key stuff says the name of the index!!
But in the docs says that InnoDB doesn't allow hash index now i wonder why my innoDB Supposedly allows the hash index?

InnoDB silently changes "HASH" into "BTree". A BTree index does what a HASH does, plus more. Or do you think there is some good reason to want Hash?
"Good reason" -- MySQL was created many years ago. It was designed to be 'lean and mean'. Many features were boiled down to "one size fits all": BTree for indexing; Nested Loop Join for JOINing, etc.
Meanwhile, for future expansion and pseudo compatibility, some common syntax variants were included -- HASH for indexing, DESC for index ordering, etc. Even though those "lie" about what will happen, the database engine still gives you the 'right' answer.
Over time, the most glaring shortcuts have been remedied.
Replication (3.xx?)
Transactions (Adding InnoDB in 4.0) (MyISAM had LOCK TABLES, but that was not really adequate.)
information_schema (4.1?) (versus a variety of SHOW commands) Note: 8.0 overhauled it with the "data dictionary")
Character sets and collations (4.1) (vs "latin_swedish_ci", which was good enough for the implementor.)
Stored routines (vs client code) (5.0)
Subqueries (TEMPORARY TABLEs were not adequate)
Various JOIN optimizations (5.6, 5,7, 8.0)
only_full_group_by (MariaDB 10.1?, 5.7)
ALTER not 'always' copying the table over (mostly 5.7)
"Generated" columns (5.7)
"Tablespaces" (5.7)
JSON datatype and functions
FULLTEXT and SPATIAL indexing in InnoDB (5.7, 8.0) (so MyISAM can be deprecated)
DESC in INDEXes (8.0) (very few use cases really need this)
"Windowing" functions (MariaDB 10.2, then MySQL 8.0)
CTEs (MariaDB 10.2, then MySQL 8.0)
Security: Better password handling (4.1?, 5.6, 8.0)
HA (High Availability) (MariaDB with Galera; 8.0 with InnoDB Cluster)
At-rest encryption (8.0?)
Notice how the list is somewhat ordered from "must have" to "nice to have". Yet to come may include
Multi-threaded execution (Useless if you are I/O-bound anyway) (a very few use cases in 8.0)
HASH indexing (and other types) (MariaDB 10.4, only for UNIQUE on TEXT/BLOB)
Global UNIQUE and FOREIGN KEY for PARTITIONing. (Not that partitioning is very useful.)
More syntax compatibility with standards and other vendors (MariaDB already does a much better job of this)
Meanwhile, some things are going away (or have already gone away -- either in MariaDB or MySQL)
Compiling for a large variety of computers -- such as Atari
The Query Cache -- Handy for benchmarking, but not really useful in Production environments. And a major hassle to implement in any 'cluster' topology.
MyISAM has major deficiencies relative to InnoDB, and has very few benefits. (Arguably, the only benefit is less disk space needed.)

The feature in InnoDB is called Adaptive Hash Index,
Whether to use hash index depends on the scale of the table and query frequency, it's a completely internal strategy and normally out of configuration.
https://dev.mysql.com/doc/refman/5.7/en/innodb-adaptive-hash.html

Related

What are the current differences between MyISAM and InnoDB storage engines specifically in MySQL 5.7?

I saw so many questions and answers on this topic MyISAM vs InnoDB on stackoverflow itself.
But, all of the questions and answers are too old and not related to the current stable version of MySQL 5.7.x
By the time so much development must have been done in both MyISAM and InnoDB.
So, I need those differences available presently with version 5.7.x
So, please don't mark my question duplicate and someone please explain the differences these storage engines have currently as well as the differences they have since past.
Also, please explain at what situation which storage engine should be chosen for a table.
Can different tables belonging to the same schema have different storage engines i.e. few tables will have InnoDB and few ones will have MyISAM.
If yes, then how the JOIN queries would get execute between tables with MyISAM and InnoDB?
Is it true that MySQL is going to remove MyISAM storage engine from the future version?
Your assumption that MyISAM has been receiving new development is not correct. MyISAM is not receiving any significant new development. MySQL is clearly moving in the direction of phasing out MyISAM, and using MyISAM is discouraged.
Oracle Corp. has not announced any specific date or version by which they will remove MyISAM. My guess is that MyISAM will never be fully removed, because there are too many sites that wouldn't be able to upgrade, without doing expensive testing to make sure their specific app won't experience any regression issues by converting to InnoDB.
But you might notice that in the MySQL 5.7 manual, the section on MyISAM has been demoted to Alternative Storage Engines, which should be a clue that it's receiving less priority.
In MySQL 5.7, MyISAM is still used for some of the system tables, like mysql.user, mysql.db, etc. But new system tables introduced in 5.6 and 5.7 are InnoDB. All system tables are InnoDB in MySQL 8.0.
MyISAM still does not support any of the properties of ACID. There are no transactions, no consistency features, and no durable writes. See my answer to MyISAM versus InnoDB.
MyISAM still does not support foreign keys, for what it's worth. But I seldom see real production sites using foreign keys even with InnoDB.
MyISAM supports only table-level locking (except for some INSERT appending to the end of a table, as noted in the manual).
MySQL 5.7 supports both fulltext indexes and spatial indexes in both MyISAM and InnoDB. These features are not reasons to continue using MyISAM as they once were.
Both logical backup tools like mysqldump and physical backup tools like Percona XtraBackup can't back up MyISAM tables without acquiring a global lock.
You asked if you could create a variety of tables with different storage engines in the same schema. Yes, you can, and this is the same as it has been for many versions of MySQL.
You asked if you can join tables of different storage engines (by the way, tables don't need to be in the same schema to be joined). Yes, you can join such tables, MySQL takes care of all the details. This is the same as it has been for many versions of MySQL.
But some weird cases can come up when you do this, like what if you update a MyISAM table and an InnoDB table in a transaction, and then roll back? The changes in the InnoDB table are rolled back, but the changes in the MyISAM table are not rolled back, so your data integrity can be broken if you aren't careful. This is also the same as it has been for many versions of MySQL.
Cases where MyISAM has an advantage over InnoDB is a short list, and it's getting shorter.
Some table-scan queries and bulk inserts are faster in MyISAM. InnoDB is better at indexed searches.
MyISAM may use less storage space than the equivalent data stored in an uncompressed InnoDB table. You can further compact MyISAM tables with myisampack, but this makes the MyISAM table read-only.
There are other options these days for compact storage of data in transactional storage engines, for example InnoDB table compression, or MyRocks.
SELECT COUNT(*) FROM MyTable queries (with no WHERE clause) are very fast in MyISAM, because the accurate count of rows is persisted in the MyISAM metadata. InnoDB (or other MVCC implementations) doesn't keep this count persisted, because every transaction viewing the table might "see" a different row count. Only a storage engine that has table-level locking and no transaction isolation like MyISAM, can optimize this case.
Auto-increment that numbers independently for each distinct value in another key column. Again, this requires table-level locking, so it's not supported in InnoDB.
CREATE TABLE MyTable (
group_id INT NOT NULL,
seq_id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (group_id, seq_id)
) ENGINE=MyISAM;
It's still easy to move a MyISAM table from server to server, because the .MYD and .MYI files are self-contained. You can kind of do something similar with InnoDB tables, but you have to use the intricate feature of transportable tablespaces. But this easy-to-move-tables quality of MyISAM no longer works in MySQL 8.0, because of their new data dictionary feature.
Under certain load, MyISAM might be a better choice for internal_tmp_disk_storage_engine, which defaults to InnoDB in MySQL 5.7. If you run lots of queries that create temp tables on disk (in-memory temp tables won't benefit), it can put a strain on the InnoDB engine. But you'd have to have a high query rate for this to matter, and if your queries create so many temp tables on disk, you should try to optimize the queries differently.
MyISAM allows you to set multiple key caches, and define caches for specific tables. But the MyISAM key caches are only for index structures, not for data.
References:
https://www.percona.com/blog/2016/10/11/mysql-8-0-end-myisam/
https://www.percona.com/blog/2017/12/04/internal-temporary-tables-mysql-5-7/
http://jfg-mysql.blogspot.com/2017/08/why-we-still-need-myisam.html
I had this question for a job quiz and got it right: (referring the new version):
MyISAM and InnoDB are two different storage engins that handle CRUD operations differently.
Locking: When approching a row inside a MyISAM storage engin, all the table will be locked by other sessions until the change is commited, unlike InnoDB, which locks only the specific selected row(/s). The lock is released until the session is commited. Locking a table or a row causes suspention by other sessions that try to interact with the same table or row to prevent wrong data manipulations in the table for example.
Transactions: InnoDB supports transactions, unlike MyISAM. Transactions are a colection of 2 or more commands like SELECT, INSERT, UPDATE and DELETE, to a single operation until complishion.
Atomic Operations: When setting a transaction in an InnoDB and
the operation is incompleted - it terminates all the changes and
restore the DB as it was (all or nothin'), so for example, if in the
middle of a transaction there is a syntax error in the code /
datatype mismatch or anything that might interupt the bundle of
commands to finish its operation - all the changes wont be applied,
thanks transactions atomicy. On the other hand, when using an
MyISAM storage engin, if a bundle of commands "breaks" (for any
reason), the operation stops immediately and all the
tables/rows/data that were affected will remain affected, which
might cause a corrupt data in the database (...and a headache).
B. Running an operation on MyISAM are set on the spot,
whereas InnoDB allows you to use the "ROLLBACK"s to discard any
change, which comes best in handy when running transactions.
Transaction Logs: When creating a transaction without a
transaction log in between, you can apply any changes on the table/s
in the DB, and if the table have a clustered index (for example),
the data will have to search where exactly it has to be inserted and
only then apply the change. In a case where there is a transaction
log in between the DB and the transaction, the changes will be sent
to the transaction log first and will set its order in the table
before sending the change to the DB - which will be less time
consuming. The DB saves logs from all the transactions that were
made, which can help to choose to restore any transaction previously
made, and recover all changes. When set to a "simple" recovery model- transactions are deleted from the transactions log and wont be able to recover data (used usually on DEV environments). When set to
"full" recovery model, all transactions are saved and listed, ready
to be restored - this is used usually on production environments
which might cause problems like preformance issues - so backing them
up and deleting from the server could be a solution. When set to a
"bulk-logged" recovery model saved transaction logs only for
specific "important" changes and commands (import,export,
insert-select, select-into, reorganaizing/rebuilding indexes), and
might prevent preformance issues.
Foreign keys: MyISAM dosn't use foreign keys, unlike InnoDB. When a table column has a foregin key set to point on an other table column, when any update/delete occures on the pointed table, it will know that the changes have to be applied on the other table pointing at it. This create a some kind of a link between the two table and keep data in sync. Setting tables with FKs might require more effort which might be considered as a disadvantage (?).
FULLTEXT indexing: InnoDB doesn't support FULLTEXT indexing in its previous versions - MyISAM does support it. Switching to MyISAM wont be the best solution so just update MySQL to a verion which does support FULLTEXT indexing.
FULLTEXT indexing can take texts like titles, comments, ect' - and search it (this should be a better option than the "LIKE" command in this case).
Spatial data types: Supported only on InnoDB.
To sum all up, InnoDB will be usually more reliable in terms of data handling, validity & recovery. For newer versions InnoDB will support FULLTEXT indexing for mainly searches - when using older versions with no option to update MySQL, using MyISAM will be great.

MyISAM performance

In Mysql (5.7 onwards) for Change tracking of a table, this approach is very simple to implement.
But it needs the versions table to be of MyISAM, which does table level locking.
Would this approach work well for production systems where multiple inserts/updates are happening every second?
Does any one have any real production systems experience about this approach?
Each table in the DB(InnoDB) has Versions table(MyISAM)
My system has the following load.
* Approx 500 reads/sec on each table due to various joins.
* And 50 writes/sec to various tables which have triggers to the versions table.
Would the versions table (MyISAM) become a bottleneck for performance?
When a MyISAM table has AUTO_INCREMENT (and a certain mode set), and no other UNIQUE keys, it will append to the table "without a lock". So, I don't think the 50 writes/sec will be an issue.
MariaDB will probably continue to include MyISAM long after Oracle jettisons it. Oracle's intent is to make InnoDB so good that there will be no need for MyISAM, and they are likely to succeed.
Secondary indexes on the versions tables may become a bottleneck. In this area, I think InnoDB's "change buffer" does a better job than MyISAM's "do it now".

Does INNODB storage engine provide default partition pruning in MySQL 5.6?

I know we can define Partition Pruning explicitly. But, I want to know if it is provided by default. I have tried the official documentation site for MySQL. The site says, "In MySQL 5.6.8 and later, partition pruning is disabled for all tables using a storage engine that provides automatic partitioning, such as the NDB storage engine used by MySQL Cluster". A quick and to the point answer with explanation will be worth.
Thanks In Advance
Short answer: Yes.
Long answer: Watch out for some subtle terminology...
InnoDB does not have "automatic partitioning"; one must explicitly specify partitioning. NDB automatically partitions the data.
InnoDB will automatically prune down to the partition(s) that the WHERE clause specifies implicitly via a condition on the 'partition key'.
But, be aware that pruning is often no better than crafting a good composite index on a non-partitioned table.
I claim there are only 4 use cases where PARTITIONing provides any performance benefit. Furthermore, I claim that BY RANGE is the only flavor that helps.
If you would like to show us your SHOW CREATE TABLE and SELECT, we can discuss whether PARTITIONing is of any benefit. And, if no benefit, why.

Creating indexes prior to LOAD DATA for performance in MySQL

The Amazon RDS Customer Data Import Guide for MySQL (written in 2009) provides the following tip to decrease load times for MySQL -
Create all secondary indexes prior to loading. This is counterintuitive for those familiar with other databases. Adding or modifying a secondary index causes MySQL to create a new table with the index changes, copy the data from the existing table to the new table, and drop the original table.
However, there are several articles and stackoverflow posts from 2010+ that provide performance tests showing that creating indexes after loading is more performant. Where did this come from and did it just apply to an older version of MySQL? If so, please provide exact details. Or, does it still apply is specific cases?
The AWS recommendation to put secondary indexes in place before loading the data applied to older MySQL versions (< 5.5) because of the way secondary indexes were handled:
From the MySQL 5.5 docs:
Creating and dropping secondary indexes has traditionally involved
significant overhead from copying all the data in the InnoDB table.
The fast index creation feature of the InnoDB Plugin makes both CREATE
INDEX and DROP INDEX statements much faster for InnoDB secondary
indexes.
MySQL offers the following recommendation in the 5.5 documentation:
Because index maintenance can add performance overhead to many data
transfer operations, consider doing operations such as ALTER TABLE ...
ENGINE=INNODB or INSERT INTO ... SELECT * FROM ... without any
secondary indexes in place, and creating the indexes afterward.
If you use MySQL 5.5 or higher with AWS, you can take advantage of the fast Fast Index Creation feature that significantly speeds up secondary indexes creation.
Fast Index Creation is a capability first introduced in the InnoDB Plugin, now part of the MySQL server in 5.5 and higher, that speeds up
creation of InnoDB secondary indexes by avoiding the need to
completely rewrite the associated table. The speedup applies to
dropping secondary indexes also.

MySQL FULLTEXT indexes issue

I’m trying to create a FULLTEXT index on an attribute of a table. Mysql returns
ERROR 1214: The used table type doesn’t support FULLTEXT indexes.
Any idea what I’m doing wrong?
You’re using the wrong type of table. Mysql supports a few different types of tables, but the most commonly used are MyISAM and InnoDB. MyISAM (in MySQL 5.6+also InnoDB tables) are the types of tables that Mysql supports for Full-text indexes.
To check your table’s type issue the following sql query:
SHOW TABLE STATUS
Looking at the result returned by the query, find your table and corresponding value in the Engine column. If this value is anything except MyISAM or InnoDB then Mysql will throw an error if your trying to add FULLTEXT indexes.
To correct this, you can use the sql query below to change the engine type:
ALTER TABLE <table name> ENGINE = [MYISAM | INNODB]
Additional information (thought it might be useful):
Mysql using different engine storage types to optimize for the needed functionality of specific tables. Example MyISAM is the default type for operating systems (besides windows), preforms SELECTs and INSERTs quickly; but does not handle transactions. InnoDB is the default for windows, can be used for transactions. But InnoDB does require more disk space on the server.
Up until MySQL 5.6, MyISAM was the only storage engine with support for full-text search (FTS) but it is true that InnoDB FTS in MySQL 5.6 is syntactically identical to MyISAM FTS. Please read below for more details.
InnoDB Full-text Search in MySQL 5.6
On MySQL <= 5.5, the mysql manual says that FULLTEXT indexes can only be created on tables with the mylsam engine.
Are you using InnoDB? The only table type that supports FULLTEXT is MyISAM.
apart from MyISAM table PARTITIONING also not support full-text index.