故事是这样的……我有用户,他们有 child 。
我想每天使用 CRON JOB 优惠券向在 child 出生日期间隔内有 child 的用户发送。
我想知道谁将成为获得优惠券的用户以及哪个 child 。
此外,我只想为每个 child 发送一张优惠券,并且该 child 必须是用户拥有的最小的 child 。
我有以下表格
Children
+--------------------------------------+
- Primary Key: childrenID (int)
- Index: userID (int)
- Index: childBirthDate (date)
+--------------------------------------+
- childrenID - userID - childBirthDate -
- 1 - 1 - 21/01/2000 -
- 2 - 1 - 01/11/2013 -
- 3 - 1 - 25/10/2013 -
- 4 - 2 - 01/11/2013 -
- 5 - 3 - 01/11/2013 -
+--------------------------------------+
Users
+------------------------+
- Primary Key: userID (int)
- Index: categoryGroup (varchar)
+------------------------+
- userID - categoryGroup -
- 1 - 'Group1' -
- 2 - 'Group1' -
- 3 - 'Group2' -
- 4 - 'Group2' -
+------------------------+
CuponRequests
+------------------------+
- Primary Key: ID (int)
- Index: userID (int)
- Index: cuponID (int)
+-----------------------+
- ID - cuponID - userID -
- 1 - 1 - 1 -
- 1 - 2 - 1 -
- 1 - 1 - 2 -
+-----------------------+
这基本上是具有相关列的三个主要表格 我有以下 SQL 查询来执行和获取我需要的结果。
SELECT users.userID,
users.categoryGroup children.childBirthDate,
children.childrenID
FROM users,
(SELECT *
FROM
(SELECT children.childrenID,
children.childBirthDate,
users.userID AS child_uid
FROM children,
users
WHERE children.userID = users.userID
ORDER BY children.childBirthDate DESC)t1
GROUP BY child_uid)children
WHERE (children.childBirthDate <= DATE_SUB(CURDATE(), INTERVAL 5 MONTH))
AND (children.childBirthDate > DATE_SUB(CURDATE() , INTERVAL 6 MONTH))
AND (children.child_uid = users.userID)
AND ('Group1, Group2' LIKE CONCAT('%', users.categoryGroup, '%'))
AND NOT EXISTS
(SELECT userID,
cuponID
FROM cuponRequests
WHERE userID = users.userID
AND cuponID = 1)
AND userID = 1
ORDER BY children.childBirthDate DESC
对于这个查询,我试图只针对一个用户和一张优惠券 但这是自然行为——查询对所有用户有效
“cuponID”和间隔来自脚本的 PHP 端 - 我迭代“cupons”表(此处未提及)并在每个“优惠券”行上执行此查询)
问题是这个查询被执行了大约 1.5 秒 (O.O) 除了在 CRON JOB 环境中运行此脚本外,此脚本还会在用户注册到网站后立即运行。我有 96 个杯子 - 这会使注册速度减慢大约一分钟(很多)
我认为这个查询
SELECT *
FROM
(SELECT children.childrenID,
children.childBirthDate,
users.userID AS child_uid
FROM children,
users
WHERE children.userID = users.userID
ORDER BY children.childBirthDate DESC)t1
GROUP BY child_uid
减慢速度。我尝试在这样的选择查询中执行 JOIN 而不是选择查询:
FROM users LEFT JOIN children ON children.userID = users.userID
但是后来我失去了“ORDER BY childBirthDate DESC”来得到这个用户最小的 child ,我失去了“GROUP BY child_uid”来得到他的一个 child
有什么想法可以让事情变得更快但仍然有效吗?
附言 对不起,我的英语不好。
编辑:
这是 EXPLAIN SQL 的输出
+----+--------------------+---------------+-------+----------------+---------+---------+------------------------------+-------+-----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+---------------+-------+----------------+---------+---------+------------------------------+-------+-----------------------------------------------------+
| 1 | PRIMARY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE noticed after reading const tables |
| 4 | DEPENDENT SUBQUERY | cuponRequests | ref | userID,cuponID | userID | 5 | const | 1 | Using where |
| 2 | DERIVED | <derived3> | ALL | NULL | NULL | NULL | NULL | 73526 | Using temporary; Using filesort |
| 3 | DERIVED | users | index | PRIMARY | PRIMARY | 4 | NULL | 69271 | Using index; Using temporary; Using filesort |
| 3 | DERIVED | children | ref | userID | userID | 4 | users.userID | 1 | |
+----+--------------------+---------------+-------+----------------+---------+---------+------------------------------+-------+-----------------------------------------------------+
最佳答案
这个查询应该快得多。我已经移动了关于出生日期的条件。
SELECT *
FROM
(SELECT children.childrenID,
children.childBirthDate,
users.userID AS child_uid
FROM children,
users
WHERE children.userID = users.userID
AND children.childBirthDate <= DATE_SUB(CURDATE(), INTERVAL 5 MONTH)
AND children.childBirthDate > DATE_SUB(CURDATE() , INTERVAL 6 MONTH)
ORDER BY children.childBirthDate DESC)t1
GROUP BY child_uid
编辑
以我能写的最快形式的完整查询。我从 LIKE 中删除了 %,将子查询更改为连接并删除了 *。关于出生日期的条件也被移动了。不过,可能会有错误。
SELECT users.userID,
users.categoryGroup, children.childBirthDate,
children.childrenID
FROM
(SELECT MIN(childBirthDate) AS childBirthDate, userID
FROM children
WHERE childBirthDate <= DATE_SUB(CURDATE(), INTERVAL 5 MONTH)
AND childBirthDate > DATE_SUB(CURDATE() , INTERVAL 6 MONTH)
GROUP BY userID) AS ch1
INNER JOIN users ON users.userID = ch1.userID
INNER JOIN children ON users.userID = children.userID AND ch1.childBirthDate = children.childBirthDate
LEFT JOIN CuponRequests ON CuponRequests.userID = userID AND cuponID = 1
WHERE ('Group1' LIKE users.categoryGroup OR 'Group2' LIKE users.categoryGroup)
AND CuponRequest.ID IS NULL
AND userID = 1
ORDER BY children.childBirthDate DESC
详细描述
ON 子句编写连接应该更安全。GROUP BY 的语句对于优化器来说更加复杂。在其中写入附加条件可能会有所帮助。LIKE '%something%' 语句很难使用索引。 LIKE 'something%' 或 LIKE 'something' 速度要快得多。* 更改为所需参数的显式列表是个好主意。有时所有需要的信息都在索引中,不需要直接从表中读取。它在极端情况下可能会有所帮助。关于php - JOINed 表上的 GROUP BY 和 ORDER BY - 复杂且缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20192181/
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
我有一个.pfx格式的证书,我需要使用ruby提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o
我在加密来self正在使用的第三方供应商的值时遇到问题。他们的指令如下:1)Converttheencryptionpasswordtoabytearray.2)Convertthevaluetobeencryptedtoabytearray.3)Theentirelengthofthearrayisinsertedasthefirstfourbytesontothefrontofthefirstblockoftheresultantbytearraybeforeencryption.4)EncryptthevalueusingAESwith:1.256-bitkeysize,2.25
我正在开发西洋跳棋实现,其中有许多易于测试的方法,但我不确定如何测试我的主要#play_game方法。我的大多数方法都可以很容易地确定输入和输出,因此也很容易测试,但这种方法是多方面的,实际上并没有容易辨别的输出。这是代码:defplay_gameputs@gui.introwhile(game_over?==false)message=nil@gui.render_board(@board)@gui.move_requestplayer_input=getscoordinates=UserInput.translate_move_request_to_coordinates(play
我了解instance_eval和class_eval之间的基本区别。我在玩弄时发现的是一些涉及attr_accessor的奇怪东西。这是一个例子:A=Class.newA.class_eval{attr_accessor:x}a=A.newa.x="x"a.x=>"x"#...expectedA.instance_eval{attr_accessor:y}A.y="y"=>NoMethodError:undefinedmethod`y='forA:Classa.y="y"=>"y"#WHATTT?这是怎么回事:instance_eval没有访问我们的A类(对象)然后它实际上将它添加到
方法应返回-1,0或1分别表示“小于”、“等于”和“大于”。对于某些类型的可排序对象,通常将排序顺序基于多个属性。以下是可行的,但我认为它看起来很笨拙:classLeagueStatsattr_accessor:points,:goal_diffdefinitializepts,gd@points=pts@goal_diff=gdenddefothercompare_pts=pointsother.pointsreturncompare_ptsunlesscompare_pts==0goal_diffother.goal_diffendend尝试一下:[LeagueStats.new(
我有一个集合选择:此方法的单选按钮是什么?谢谢 最佳答案 Rails3中没有这样的助手。在Rails4中,它是collection_radio_buttons. 关于ruby-on-rails-rails上的ruby:radiobuttonsforcollectionselect,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/18525986/
我正在尝试将cucumber项目的用户名和密码置于版本控制之外。有没有办法在命令行上手动将用户名和密码等变量传递给Cucumber脚本?我的备份计划是将它们放在一个YML文件中,然后将该文件添加到gitignore,这样它们就不会被置于版本控制中。 最佳答案 所以,我看到了您对铁皮人的评论,答案是肯定的。cucumberPASSWORD=my_passwordPASSWORD被设置为环境变量,您可以通过将其引用为ENV['PASSWORD']来使用它的值。例如,browser.text_field(:id=>'pwd').setEN