聚集索引:指索引项的排序方式和表中数据记录排序方式一致的索引(这里不懂先放着,一会举例),每张表只能有一个聚集索引,聚集索引的叶子节点存储了整个行数据。 辅助索引:辅助索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同,一个表中可以拥有多个非聚集索引。叶子节点并不包含行记录的全部数据。叶子节点除了包含键值以外,还存储了一个指向改行数据的聚集索引建的书签。
1.想到查询所有商品最近的一次分享记录,并且当没有最近的分享时候能生成空记录
利用先排序后分组的思路,避免子查询的排序失效,用了limit来保证;然后子查询里面放置
2.查询时间为+5.5并且按照天分组,计算每天结果去重后的数量
select DATE_FORMAT(DATE_ADD(wcate.create_at, INTERVAL 5.5 hour),'%Y%m%d') as wcate_create_at, count(DISTINCT wcate.wcate_code), count(DISTINCT wsku.product_code), count(DISTINCT wsku.id) from wsku join wcate on wsku.wcate_id=wcate.id GROUP BY wcate_create_at ORDER BY wcate_create_at desc
3.缓存池超过使用的范围,连接超时
sqlalchemy.exc.TimeoutError: QueuePool limit of size 10 overflow 10 reached, connection timed out, timeout 10 (Background on this error at: http://sqlalche.me/e/3o7r)
出现这个错的时候一般后端的表现为有部分请求非常慢,或者大部分请求都非常慢,如果后端频繁出现这个问题的时候,可以根据这两种情况进行分析: Flask-SQLAlchemy 默认给你的 session 是一个 scoped_session,是一个 ThreadLocal 的对象,在大部分情况下,一个线程里拿到的都是同一个 session,你可以多次调用 db.session() 观察其 id,当你 db.session.remove() 了一次后,db.session() 才会拿到不一样的 session。
1.批量插入数据sqlalchemy.orm.session
2.返回值
select = db.session.query(Wcate).first()
<Wcate 4> Wcate对象
select = db.session.query(Wcate.id).first()
(1001,) 需要解包
3.execute() 函数本身有接受sql语句参数位的,可以通过python自身的函数处理sql注入问题。
用session(orm)执行,第二个参数是字典,用cursor(pymysql)执行,第二个参数是元组
4.orderby和limit同时使用,如果你需要确保无论带不带LIMIT都要以相同的顺序返回,那么你可以在ORDER BY中包含附加列,如id(自带索引)
5. 如果你将LIMIT row_count子句与ORDER BY子句组合在一起使用的话,MySQL会在找到排序结果的第一个row_count行后立即停止排序,而不是对整个结果进行排序。 所以同时用的时候,order by字段不用索引。
6.limit 2000, 20。 1.扫描2020行,丢掉2000行,减少查询的量,尽量通过主键覆盖的的字段先排完序后,再查询其他数据;2.通过记录上次查询的主键的最后一位id,先判断id,只取20条, where MemberID >= (select MemberID from Member limit 100000,1)
7.Cursor,以元组的方式保存,DictCursor是以字典的形式保存 SSCursor和SSDictCursor流式游标,这类游标不会像上面使用的Cursor和DictCursor那样,一次性返回所有的数据,流式游标会陆陆续续一条一条得返回查询数据,所以这类游标适用于内存低、网络带宽小、数据量大的应用场景中。要配合cursor.fetchone()
8.多个表一起查询,右链接不生效
select wcate.id, max(IFNULL(t.is_notify, 1)) from wcate left join wsku on wsku.wcate_id = wcate.id left join offer on offer.wsku_id = wsku.id left join (SELECt reseller_notify.offer_id, reseller_notify.reseller_id, reseller_notify.is_notify from reseller_notify where reseller_notify.reseller_id = 1001 ) t on t.offer_id = offer.id where wcate.id in (1520, 1521) GROUP BY wcate.id ;
9.Deadlock found when trying to get lock; try restarting transaction
通过查询资料知道,对有索引的字段更新数据会用行级锁,其他的时候是表级锁;此处应该是用到行级锁但是仍然死锁,
ab -c 10 -n 10 -T 'application/json' -H 'token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1Njc1MTk5NDEsImV4cCI6MTU3MDExMTk0MSwic291cmNlX3R5cGUiOjMsInVpZCI6MTEyOSwiZGV2aWNlX2lkIjo0NDQxNTUwMX0.nlUrilI99H9FpxDFnLTyu0_JLBzSN29j7p6CUqDIkmE' -s 120 -p /home/test/productcate.txt https://test.thewemore.com/api/v1.0/product/productcate
通过ab大量跑复现,发现是orm修改和execute两处修改,都未提交导致死锁的。
行级锁并不是直接锁记录,而是锁索引,如果一条SQL语句用到了主键索引,mysql会锁住主键索引;如果一条语句操作了非主键索引,mysql会先锁住非主键索引,再锁定主键索引。如果操作用到了主键索引会先在主键索引上加锁,然后在其他索引上加锁,否则加锁顺序相反
# case when
select B.`userId`,SUM(B.`change`), B.`Atype` FROM (select A.`userId`,A.`change`, (case when A.`type` =1 or A.`type`=5 then 1 when A.`type` =2 or A.`type` then 3 else 2 end ) `Atype1` FROM `xc_ebike_user_wallet_record` A ) B GROUP BY B.`userId`, B.`Atype`
#多列变成多行
SELECt D.id, D.balance, D.recharge, D.present, C.change1, C.change2, C.change3 FROM xc_ebike_usrs_2 D JOIN (select B.`userId`,SUM(B.`change1`),SUM(B.`change2`),SUM(B.`change3`) FROM (select A.`userId`, IF(A.`type` =1 or A.`type`=5, A.`change`, 0) AS change1, IF(A.`type` =3 or A.`type`=4 or A.`type`=6 or A.`type`=7 or A.`type`=8, A.`change`, 0) AS change2, IF(A.`type` =2, A.`change`, 0) AS change3 FROM `xc_ebike_user_wallet_record` A) B GROUP BY B.`userId`) C ON C.userId=D.id
10、 select * from A join B on A.id =B.Aid and B.type=1 select * from A join B on A.id =B.Aid where B.type=1 不一致问题,原因,坏处
11. 创表的时候,让数据库ddl配置字段默认值
12.orm批量插入或编辑: