需要简单查询的索引

时间:2019-01-18 10:43:41

标签: mysql sql

有人可以建议一个好的索引来使此查询更快地运行吗?

SELECT 
    s.*, 
    sl.session_id AS session_id, 
    sl.lesson_id AS lesson_id
FROM 
    cdu_sessions s
INNER JOIN cdu_sessions_lessons sl ON sl.session_id = s.id
WHERE  
    (s.sort = '1') AND 
    (s.enabled = '1') AND 
    (s.teacher_id IN ('193', '1', '168', '1797', '7622', '19951'))

说明:

id | select_type | table | partitions | type | possible_keys  | key  | key_len | ref                | rows | filtered  | Extra
1  | SIMPLE      | s     | NULL       | ALL  | PRIMARY        | NULL | NULL    | NULL               | 2993 | 0.50      | Using where
1  | SIMPLE      | sl    | NULL       | ref  | session_id,ix2 | ix2  | 4       | ealteach_main.s.id | 5    | 100.00    | Using index

cdu_sessions看起来像这样:

------------------------------------------------
id                            | int(11)
name                          | varchar(255)
map_location                  | enum('classroom', 'school'...)
sort                          | tinyint(1)
sort_titles                   | tinyint(1)
friend_gender                 | enum('boy', 'girl'...)
friend_name                   | varchar(255)
friend_description            | varchar(2048)
friend_description_format     | varchar(128)
friend_description_audio      | varchar(255)
friend_description_audio_fid  | int(11)
enabled                       | tinyint(1)
created                       | int(11)
teacher_id                    | int(11)
custom                        | int(1)
------------------------------------------------

cdu_sessions_lessons包含3个字段-id,session_id和lesson_id

谢谢!

3 个答案:

答案 0 :(得分:2)

如果不查看查询计划,每个表的行数和分布,很难预测一个好的索引以使其运行更快。

但是,我想这可能会有所帮助:

> INFO: Deployment of web application archive C:\Users\e4560\Desktop\address-manager\application\target\apache-tomee\webapps\ROOT.war has finished in 12,030 ms
Jan 18, 2019 10:31:57 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
Jan 18, 2019 10:31:57 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
Jan 18, 2019 10:31:57 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 12240 ms
Jan 18, 2019 10:31:57 AM org.apache.catalina.core.StandardServer await
SEVERE: StandardServer.await: create[localhost:8005]:
java.net.BindException: Address already in use: JVM_Bind
        at java.net.DualStackPlainSocketImpl.bind0(Native Method)
        at java.net.DualStackPlainSocketImpl.socketBind(DualStackPlainSocketImpl.java:106)
        at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)
        at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:190)
        at java.net.ServerSocket.bind(ServerSocket.java:375)
        at java.net.ServerSocket.<init>(ServerSocket.java:237)
        at org.apache.catalina.core.StandardServer.await(StandardServer.java:444)
        at org.apache.catalina.startup.Catalina.await(Catalina.java:782)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:728)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:294)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:428)
Jan 18, 2019 10:31:57 AM org.apache.coyote.AbstractProtocol pause
INFO: Pausing ProtocolHandler ["http-bio-8080"]
Jan 18, 2019 10:31:57 AM org.apache.coyote.AbstractProtocol pause
INFO: Pausing ProtocolHandler ["ajp-bio-8009"]
Jan 18, 2019 10:31:57 AM org.apache.catalina.core.StandardService stopInternal
INFO: Stopping service Catalina
Jan 18, 2019 10:31:57 AM org.apache.openejb.assembler.classic.Assembler destroyApplication
INFO: Undeploying app: C:\Users\e09340\Desktop\address-manager\application\target\apache-tomee\webapps\ROOT
Jan 18, 2019 10:31:57 AM org.apache.openejb.util.OptionsLog info
INFO: Using 'openjpa.Log=org.apache.openejb.openjpa.JULOpenJPALogFactory'
Jan 18, 2019 10:31:57 AM org.apache.openejb.assembler.classic.Assembler destroyApplication
INFO: Undeployed app: C:\Users\epom\Desktop\address-manager\application\target\apache-tomee\webapps\ROOT
Jan 18, 2019 10:31:57 AM org.apache.catalina.loader.WebappClassLoaderBase checkThreadLocalMapForLeaks
SEVERE: The web application [] created a ThreadLocal with key of type [com.netflix.hystrix.Hystrix$1] (value [com.netflix.hystrix.Hystrix$1@4eedec61]) and a value of type [com.netflix.hystrix.Hystrix.ConcurrentStack] (value [com.netflix.hystrix.Hystrix$ConcurrentStack@740a0cb2]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
Jan 18, 2019 10:31:57 AM org.apache.coyote.AbstractProtocol stop
INFO: Stopping ProtocolHandler ["http-bio-8080"]
Jan 18, 2019 10:31:57 AM org.apache.coyote.AbstractProtocol stop
INFO: Stopping ProtocolHandler ["ajp-bio-8009"]
Jan 18, 2019 10:31:57 AM org.apache.openejb.server.SimpleServiceManager stop
INFO: Stopping server services
Jan 18, 2019 10:31:57 AM org.apache.coyote.AbstractProtocol destroy
INFO: Destroying ProtocolHandler ["http-bio-8080"]
Jan 18, 2019 10:31:57 AM org.apache.coyote.AbstractProtocol destroy
INFO: Destroying ProtocolHandler ["ajp-bio-8009"]

答案 1 :(得分:1)

查看可以在哪里使用表cdu_sessions的复合索引

create index idx1 on cdu_sessions(teacher_id, sort, enabled);

并希望加入并选择表cdu_sessions_lessons

create index idx2 on cdu_sessions_lessons(session_id, lesson_id);

答案 2 :(得分:0)

首先,编写查询,因此不需要类型转换。 where子句中的所有比较都是对数字的比较,因此请使用数字常量:

SELECT s.*,
       sl.session_id,  -- unnecessary because s.id is in the result set
       sl.lesson_id
FROM cdu_sessions s INNER JOIN
     cdu_sessions_lessons sl
     ON sl.session_id = s.id
WHERE s.sort = 1 AND 
      s.enabled = 1 AND 
      s.teacher_id IN (193, 1, 168, 1797, 7622, 19951);

尽管在这种特定情况下可能不会发生,但是混合类型会阻碍索引的使用。

我删除了该列作为别名(例如as session_id)。这些都是多余的,因为列名是别名,并且查询没有更改名称。

对于此查询,请首先查看WHERE子句。所有列引用均来自一张表。这些应该放在索引中,首先进行相等比较:

create index idx_cdu_sessions_4 on cdu_sessions(sort, enabled, teacher_id, id)

我添加了id,因为它也用在JOIN中。  正式地,如果索引id是主键,则它是不需要的。但是,如果我想要在那里,我喜欢明确表达。

接下来,您要为第二张表建立索引。从那里仅引用两列,因此它们都可以进入索引。第一列应该是join中使用的列:

create index idx_cdu_sessions_lessons_2 on cdu_sessions_lessons(session_id, lesson_id);