Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/workflows/index-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Index review

# The repository runs its own GitHub Action on every pull request that touches
# SQL or Mapper XML. Two things are proven by this file existing: the `uses:` ref
# in the README resolves, and a contributor gets advice on the line they changed
# without anyone installing anything.
#
# `fail-on: off` on purpose. Adoption first: the check comments, it does not
# redden the build. A team that wants a gate changes it to `error` in their own
# copy (see examples/github-action/pr-review.yml).

on:
pull_request:
paths:
- "**/*.xml"
- "**/*.sql"
- "examples/**"

permissions:
contents: read
pull-requests: write

jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Index review
uses: JingYu-create520/sql-index-advisor@v0
with:
path: examples/pr-demo
schema: examples/pr-demo/demo-schema.json
min-severity: info
fail-on: "off"
41 changes: 41 additions & 0 deletions examples/pr-demo/OrderSearchDao.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
Deliberately imperfect, so the Action that reviews this repository has something
to say. Each statement below is a shape the rule engine recognises: a join key
with no index, a function on an indexed column, a leading-wildcard LIKE that no
index can serve, and a hand-written deep offset. Keep this file; deleting it
would make the workflow that checks it say nothing, which proves less.
-->
<mapper namespace="com.example.demo.dao.OrderSearchDao">

<select id="listByShop" resultType="com.example.demo.model.OrderView">
SELECT o.id, o.order_sn, o.status, d.amount
FROM demo_order o
JOIN demo_order_detail d ON d.order_id = o.id
WHERE o.shop_id = #{shopId}
AND o.delete_status = 0
ORDER BY o.create_time DESC
</select>

<select id="countByDay" resultType="long">
SELECT COUNT(*)
FROM demo_order
WHERE DATE(create_time) = #{day}
</select>

<select id="search" resultType="com.example.demo.model.OrderView">
SELECT id, order_sn, receiver_name
FROM demo_order
WHERE receiver_name LIKE concat('%', #{keyword}, '%')
LIMIT #{offset}, 20
</select>

<select id="scrollPage" resultType="com.example.demo.model.OrderView">
SELECT id, order_sn
FROM demo_order
ORDER BY create_time DESC
LIMIT 120000, 20
</select>

</mapper>
41 changes: 41 additions & 0 deletions examples/pr-demo/demo-schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"mysqlVersion": "8.0.46",
"tables": [
{
"name": "demo_order",
"engine": "InnoDB",
"charset": "utf8mb4",
"rowCountEstimate": 480000,
"columns": [
{ "name": "id", "type": "bigint", "nullable": false },
{ "name": "order_sn", "type": "varchar", "length": 32, "charset": "utf8mb4", "nullable": false },
{ "name": "shop_id", "type": "bigint", "nullable": false },
{ "name": "user_id", "type": "bigint", "nullable": false },
{ "name": "status", "type": "tinyint", "nullable": false },
{ "name": "delete_status", "type": "tinyint", "nullable": false },
{ "name": "receiver_name", "type": "varchar", "length": 64, "charset": "utf8mb4", "nullable": true },
{ "name": "amount", "type": "decimal", "nullable": false },
{ "name": "create_time", "type": "datetime", "nullable": true }
],
"indexes": [
{ "name": "PRIMARY", "unique": true, "primary": true, "columns": ["id"], "subParts": [null] }
]
},
{
"name": "demo_order_detail",
"engine": "InnoDB",
"charset": "utf8mb4",
"rowCountEstimate": 1250000,
"columns": [
{ "name": "id", "type": "bigint", "nullable": false },
{ "name": "order_id", "type": "bigint", "nullable": false },
{ "name": "product_id", "type": "bigint", "nullable": false },
{ "name": "quantity", "type": "int", "nullable": false },
{ "name": "amount", "type": "decimal", "nullable": false }
],
"indexes": [
{ "name": "PRIMARY", "unique": true, "primary": true, "columns": ["id"], "subParts": [null] }
]
}
]
}
Loading