Мне трэба, каб дадаць індэкс на ORDER BY поля ці што?

У мяне ёсць запыт аб такіх, як

$query = "SELECT * FROM tbl_comments WHERE id=222 ORDER BY comment_time";

Мне трэба дадаць індэкс на COMMENT_TIME поля ці што?

Акрамя таго, калі я хачу, каб атрымаць дадзеныя паміж двума датамі, то як я павінен пабудаваць індэкс?

7
На жаль, няма так/няма адказу на гэтае пытанне - гэта сапраўды залежыць ад некалькіх фактараў, такіх як памер вашай табліцы, лік слупкоў у табліцы, іншага лік паказчыкаў, выдаткі і выгады для чытання/запісы і г.д. Лепш за ўсё, паспрабаваць і паглядзець на вашы планы выканання. Што тычыцца даты, проста шукаць што - але я б рэкамендаваў выкарыстоўваць> = і <= замест Між пры працы з датамі.
дададзена аўтар sgeddes, крыніца
Дзіўна, што слупок з назвай «Ідэнтыфікатар» не будзе на ПК, але ў бок Ці вы ці не індэкса COMMENT_TIME не паўплывае на вынік - але гэта можа павысіць прадукцыйнасць. См dev.mysql.com/doc/refman/5.0 /en/order-by-optimization.html
дададзена аўтар Strawberry, крыніца
Хм. не ўпэўнены .. але вы можаце паспрабаваць папярэднічаць EXPLAIN для запыту і паглядзім на тое, што эфект індэксным мае. Акрамя таго, атрыманне дадзеных ад 2 значэнняў называецца пошук па дыяпазоне, ёсць погляд на MySQL дакументы на тым, што dev.mysql.com/doc/refman/5.0/en/range-optimization.html
дададзена аўтар Johan, крыніца

7 адказы

Так, індэкс дапаможа, пры выкарыстанні ORDER BY. Паколькі індэкс ўяўляе сабой адсартаваны структуру дадзеных, таму запыт будзе выконвацца хутчэй.

Паглядзіце на гэты прыклад: табліца test2 з 3-ма радамі. Я выкарыстаў LIMIT пасля парадку, каб паказаць розніцу ў выкананні.

DROP TABLE IF EXISTS `test2`;
CREATE TABLE `test2` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `value` varchar(10) CHARACTER SET utf8 COLLATE utf8_swedish_ci NOT NULL,
  PRIMARY KEY (`id`),
  KEY `ix_value` (`value`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of test2
-- ----------------------------
INSERT INTO `test2` VALUES ('1', '10');
INSERT INTO `test2` VALUES ('2', '11');
INSERT INTO `test2` VALUES ('2', '9');

-- ----------------------------
-- Without INDEX
-- ----------------------------

mysql> EXPLAIN SELECT * FROM test2 ORDER BY value LIMIT 1\G
*************************** 1. row *************************
           id: 1
  select_type: SIMPLE
        table: test2
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 3
        Extra: Using filesort
1 row in set (0.00 sec)

MySQL праверыў 3 радкі для вываду выніку. Пасля таго, як CREATE INDEX, мы атрымаем наступнае:

mysql> CREATE INDEX ix_value ON test2 (value) USING BTREE;
Query OK, 0 rows affected (0.14 sec)

-- ----------------------------
-- With INDEX
-- ----------------------------

mysql> EXPLAIN SELECT * FROM test2 ORDER BY value LIMIT 1\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test2
         type: index
possible_keys: NULL
          key: ix_value
      key_len: 32
          ref: NULL
         rows: 1
        Extra: Using index
1 row in set (0.00 sec)

Цяпер MySQL выкарыстоўваецца толькі адзін радок.

Адказы на атрыманыя каментары, я паспрабаваў адзін і той жа запыт без LIMIT:

-- ----------------------------
-- Without INDEX
-- ----------------------------

mysql> EXPLAIN SELECT * FROM test2 ORDER BY value\G
*************************** 1. row ******************
           id: 1
  select_type: SIMPLE
        table: test2
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 3
        Extra: Using filesort

-- ----------------------------
-- With INDEX
-- ----------------------------

mysql> EXPLAIN SELECT * FROM test2 ORDER BY value\G
*************************** 1. row *****************
           id: 1
  select_type: SIMPLE
        table: test2
         type: index
possible_keys: NULL
          key: ix_value
      key_len: 32
          ref: NULL
         rows: 3
        Extra: Using index

Як мы бачым, ён выкарыстоўвае індэкс, для 2-й ORDER BY .

Для пабудовы індэкса на вашым поле, выкарыстоўвайце:

CREATE INDEX ix_comment_time ON tbl_comments (comment_time) USING BTREE;

http://dev.mysql.com/doc/refman/5.0 /en/create-index.html

5
дададзена
@ypercube вынікі эксперыменту. Без індэкса: 99901 радкоў у наборы (1,72 сек) . Затым выйшаў з MySQL, а затым ўвайсці ў сістэму, зрабіў Скід QUERY CACHE; , затым створаны індэкс. 99901 радкоў у наборы (0,34 сек). Чаму?
дададзена аўтар user4035, крыніца
@ypercube Так, я згодны. Адказ:
дададзена аўтар user4035, крыніца
@GordonLinoff Я спрабаваў без LIMIT, вынік быў той жа: «Extra: Выкарыстанне FileSort» і «Дадаткова: Выкарыстанне індэкса»
дададзена аўтар user4035, крыніца
@Strawberry Растлумачце, што вы маеце на ўвазе.
дададзена аўтар user4035, крыніца
@Strawberry Так, таму што калі вы паглядзіце на тлумачэнні да стварэння індэкса, ён кажа: «Extra: Выкарыстанне FileSort». І пасля таго, як - «Выкарыстанне індэкса». Калі MySQL не можа выкарыстоўваць індэкс для атрымання Адсартавана выніку, ён павінен сартаваць сам радка. Ён можа зрабіць гэта ў памяці або на дыску, але ён заўсёды называе гэты працэс FileSort (з High Performance MySQL). Такім чынам, гэта не сартуе запісу ў другім выпадку, і запыт павінен быць выкананы хутчэй.
дададзена аўтар user4035, крыніца
@ User4035. , , Гэта ўсё вельмі цікава, але гэта не пытанне ў гэтым пытанні.
дададзена аўтар Gordon Linoff, крыніца
Вы сапраўды думаеце, гэта мае значэнне (калі індэкс выкарыстоўваецца ці не) з 3-ма радамі? Паспрабуйце з 3 тыс ці 3 мільёны радкоў і паведаміце нам.
дададзена аўтар ypercubeᵀᴹ, крыніца
@NiklasModess Гэта правільна, але для запытаў, якія маюць LIMIT . Калі вы хочаце замовіць ўсю табліцу, не можа быць выкарыстаны горада. MySQL можа выбраць (разумна), каб атрымаць усю табліцу і сартавання.
дададзена аўтар ypercubeᵀᴹ, крыніца
Даказвае Ці ваша тлумачэнне, што "індэкс дапаможа, пры выкарыстанні ORDER BY?
дададзена аўтар Strawberry, крыніца
Ці сабой гэта «доказ»?
дададзена аўтар Strawberry, крыніца
@Strawberry, што ён кажа цалкам правільна.
дададзена аўтар Niklas Modess, крыніца

Індэкс на COMMENT_TIME Поле не можа дапамагчы наогул для запыту, як гэта:

SELECT *
FROM tbl_comments
WHERE id=222
ORDER BY comment_time;

Запыт павінен сканаваць табліцу, каб знайсці адпаведнасць ID значэння. Ён можа зрабіць гэта шляхам сканавання індэкса, гледзячы ўверх радкі, і рабіць тэст. Калі ёсць адна радок, якая адпавядае і мае highext COMMENT_TIME , то гэта патрабуе сканавання індэкса і чытання табліцы.

Без індэкса, ён будзе сканаваць табліцу, знайдзіце радок, і вельмі хутка сартаваць 1 радок. Прагляд табліцы, як правіла, будзе хутчэй, чым прагляд індэкса з наступным пошукам старонкі (і, безумоўна, будзе хутчэй на стале больш, чым даступная памяць).

З іншага боку, індэкс ід, COMMENT_TIME было б вельмі карысна.

1
дададзена

Тэхнічна вам не патрэбныя індэксы на кожным полі, так як яна таксама будзе працаваць, аднак па меркаваннях прадукцыйнасці, вам можа спатрэбіцца адзін ці больш.

<�Моцны> Змяніць

Гэтая праблема вядомая з пачатку распрацоўкі праграмнага забеспячэння. Як правіла, калі павялічыць аб'ём памяці, які выкарыстоўваецца праграмай, вы паменшыце хуткасць перадачы дадзеных (мяркуючы, што праграма добра напісана). Прысваенне індэкса ў дадзенае поле павялічваецца, выкарыстоўваным у бдзе, але робіць пошук хутчэй. Калі вы не хочаце шукаць што-небудзь па гэтым полі (вы на самой справе ў гэтым пытанні), то не было б неабходнасці.

У сучасную эпоху індэксы не так вялікія ў параўнанні з памерам дадзеных на дыску і даданне аднаго або больш не павінна быць дрэннай ідэяй.

Звычайна гэта вельмі цяжка, вядома, сказаць «мне нужен індэкс ці не». Некаторую дапамогу прадастаўляецца EXPLAIN заяву ( звярніцеся да кіраўніцтва ).

1
дададзена
Я адрэдагаваў мой каментар, але больш інфармацыі вы атрымаеце ў іншых адказах
дададзена аўтар Voitcus, крыніца
Але калі я паставіў індэкс па COMMENT_TIME ці будзе яно палепшыць прадукцыйнасць?
дададзена аўтар Munib, крыніца

Што тычыцца першага пытання, то вы не павінны ствараць індэкс па COMMENT_TIME. Калі колькасць запісаў вельмі вялікае вам патрэбныя індэксы, каб паскорыць пошук. Але для працы вам не патрэбныя індэксы. Для вашага другога пытання з выкарыстаннем прапановы WHERE, як гэта дапаможа вам.

WHERE(comment_time BETWEEN 'startDate' AND 'endDate');
1
дададзена
@Strawberry З «двукоссямі» вы маеце на ўвазе адзінарныя двукоссі? На самай справе яны не з'яўляюцца такім жа, як назад абцугамі, але дзе вы бачыце неабходнасць у спіне абцугі?
дададзена аўтар glglgl, крыніца
Ananth, прабачце - я няправільна зразумеў ваш пост
дададзена аўтар Strawberry, крыніца

Вам не трэба ставіць індэкс на COMMENT_TIME, калі ваш, дзе ідэнтыфікатар адрозніваецца.

0
дададзена

Для таго, каб павялічыць хуткасць пошуку дадзеных вы павінны горада. Гэта будзе працаваць з індэксам з таксама. Для вашага другога пытання, вы можаце выкарыстоўваць WHERE і паміж тэгамі п.

Refer: http://www.w3schools.com/sql/sql_between.asp

0
дададзена

EXPLAIN заява вельмі карысна ў такіх сітуацыях. Для вашага запыту, вы павінны выкарыстоўваць яго наступным чынам:

EXPLAIN SELECT * FROM tbl_comments WHERE id=222 ORDER BY comment_time

Гэта выведзе, якія індэксы выкарыстоўваюцца для выканання запыту і дазваляюць праводзіць эксперыменты з рознымі індэксамі, каб знайсці аптымальную канфігурацыю. Для таго, каб паскорыць сартаванне, вы хочаце, індэкс ВТКЕЯ, паколькі ён захоўвае дадзеныя ў адсартаваным парадку. Для паскарэння пошуку элементаў з вызначаным ідэнтыфікатарам, індэкс HASH з'яўляецца лепшым варыянтам, так як яна забяспечвае хуткі прагляд для прэдыкатаў роўнасці. Звярніце ўвагу, што MySQL не можа быць у стане выкарыстаць камбінацыю абодвух індэксаў, каб выканаць запыт і замест гэтага будзе выкарыстоўваць толькі адзін з іх.

Further information: http://dev.mysql.com/doc/refman/5.7/en/using-explain.html

Для прэдыкатаў дыяпазону, як даты ў дыяпазоне дат, індэкс BTREE будзе працаваць лепш, чым індэкс HASH.

Further information: http://dev.mysql.com/doc/refman/5.7/en/create-index.html

0
дададзена