Active databases provide reactive functionality by supporting event-condition-action rules of the form `on $event$ if $condition$ do $actions$'. A key issue for active databases is optimising the run-time execution of such rules. Given the data-intensive nature of the rules, previous research has aimed at either adopting existing database optimisation techniques, or developing special-purpose solutions for improving execution efficiency. In contrast, in this paper we show how the programming language framework of {\em partial evaluation} provides a formal and general route to optimising active database rules. Partial evaluation \cite{JGS93} aims to improve program efficiency by producing specialised versions of the program for specific input values. In the case of sets of active rules, the `program' being optimised is the rule execution semantics and the `input values' are the current database state and the rule actions currently awaiting execution. Producing a specialised vers ion of the rule execution semantics for each possible sequence of actions that may execute on that database state provides the opportunity to optimise rule execution for each particular sequence of actions, for example by abstraction of common sub-queries from the sequences of conditions that will need to be evaluated. We obtain information about possible sequences of actions by applying {\em abstract interpretation} to the rule execution semantics, using an abstract representation of the current database state and current action(s) awaiting execution. In \cite{BP99c}, we presented a framework for termination analysis of active rules using abstract interpretation. Here, we use similar techniques for generating the set of input values with respect to which the rule execution semantics should be partially evaluated and optimised. Our techniques are applicable both statically, i.e. at rule compilation time, and dynamically, during rule execution. The contributions of this work are as follows: We introduce for the first time partial evaluation and abstract interpretation as techniques for globally optimising sets of active rules. The combination of these techniques generalises a number of optimisations already found in the active database literature. A key difference between this previous work and our approach is that our optimisations are automatically derived using general principles. This places rule optimisation on a sound theoretical footing, and also provides the opportunity to discover new optimisations. In particular, we show how abstract interpretation can be used to generate information about sequences of rule actions that will be executed, and this approach produces more possibilities for rule optimisation than previous graph-based analyses.